101 lines
1.8 KiB
C
101 lines
1.8 KiB
C
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <stdbool.h>
|
|
|
|
#define NUM_TOTAL 12
|
|
#define NUM_COLUMN 4
|
|
#define NUM_CROP 5
|
|
|
|
typedef struct {
|
|
char crop[ NUM_CROP ];
|
|
char flag[ NUM_CROP ];
|
|
} st;
|
|
|
|
|
|
void chk( char *buf, int len )
|
|
{
|
|
for ( int i = 0; i < len; i++ ) {
|
|
printf( "%d ", *buf++ );
|
|
}
|
|
printf( "\n" );
|
|
}
|
|
|
|
|
|
bool next( st *g )
|
|
{
|
|
for ( int i = NUM_CROP - 1; i >= 0; i-- )
|
|
if ( NUM_TOTAL - NUM_CROP > g->crop[ i ] - i ) {
|
|
g->crop[ i++ ] += 1;
|
|
|
|
for ( ; i < NUM_CROP; i++ )
|
|
g->crop[ i ] = g->crop[ i - 1 ] + 1;
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
char flag_set( st *g, int index, char target_flag )
|
|
{
|
|
char cur_flag = g->flag[ index ];
|
|
g->flag[ index ] = target_flag;
|
|
if ( cur_flag )
|
|
for ( int i = 0; i < index; i++ )
|
|
if ( g->flag[ i ] == cur_flag )
|
|
g->flag[ i ] = target_flag;
|
|
return 1;
|
|
}
|
|
|
|
|
|
bool continuity( st *g )
|
|
{
|
|
char base_flag = 1;
|
|
memset( g->flag, 0, NUM_CROP );
|
|
|
|
for ( int j = 0; j < NUM_CROP; j++ ) {
|
|
char connected = 0;
|
|
|
|
for ( int i = 0; i < j; i++ ) {
|
|
switch ( g->crop[ j ] - g->crop[ i ] ) {
|
|
|
|
case NUM_COLUMN:
|
|
connected += flag_set( g, j, g->flag[ i ] );
|
|
break;
|
|
|
|
case 1:
|
|
if ( g->crop[ j ] % NUM_COLUMN )
|
|
connected += flag_set( g, j, g->flag[ i ] );
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( ! connected ) g->flag[ j ] = base_flag++;
|
|
}
|
|
|
|
char cur_flag = g->flag[ 0 ];
|
|
for ( int i = 1; i < NUM_CROP; i++ )
|
|
if ( g->flag[ i ] != cur_flag )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
int main()
|
|
{
|
|
st g;
|
|
for ( int i = 0; i < NUM_CROP; i++ ) {
|
|
g.crop[ i ] = i;
|
|
}
|
|
|
|
int count = 0;
|
|
do {
|
|
if ( continuity( &g ) ) count += 1;
|
|
} while ( next( &g ) );
|
|
|
|
printf( "%d\n", count );
|
|
return 0;
|
|
}
|