#include <stdio.h>
#define OFF 0
#define ON 1
typedef struct {
int x;
int y;
} XY;
int b1[64]; /* ナイトを置く盤 /*
static XY c1[] = { /* ナイトの飛び先の相対座標 /*
2,1 , 1,2 , -1,2 , -2,1 , 2,-1 , -2,-1 , 1,-2 , -1,-2};
int kj1[64][8]; /* ナイトの飛び先(全部) /*
int nkj1[64]; /* ナイトの飛び先の数 /*
int kj2[64][9]; /* ナイトの飛び先(最小地から最大地へのみ) /*
int nkj2[64]; /* ナイトの飛び先の個数 /*
int minn1 = 8; /* ナイトの個数の最小値 /*
int count = 0; /* 通り /*
int pk1[64]; /* ナイトが置かれていく順番 /*
static int pk2[] = { /* ナイトを置いていく順番 /*
0,7,56,63,1,2,3,4,5,6,8,9,10,11,12,13,
14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,
30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,
46,47,48,49,50,51,52,53,54,55,57,58,59,60,61,62};
/* 初期化処理 /*
void init()
{
int x , y , xy = 0 , i , j;
int x1 , y1 , xy1;
int min;
for(i = 0 ; i < 64 ; i++) {
pk1[pk2[i]] = i;
b1[i] = 0;
nkj1[i] = 0;
nkj2[i] = 0;
}
for(i = 0 ; i < 64 ; i++) {
x = pk2[i] % 8;
y = pk2[i] / 8;
min = i;
for(j = 0 ; j < 8 ; j++) {
x1 = x + c1[j].x;
if(x1 < 0 || x1 > 7) continue;
y1 = y + c1[j].y;
if(y1 < 0 || y1 > 7) continue;
xy1 = pk1[y1 * 8 + x1];
kj1[i][nkj1[i]] = xy1;
nkj1[i]++;
if(xy1 < min) min = xy1;
}
kj2[min][nkj2[min]] = i;
nkj2[min]++;
}
}
/* ナイトを置けるかチェックし、置けるなら置く /*
int putKnight(int xy)
{
int i;
if(b1[xy] != 0) return(OFF);
for(i = 0 ; i < nkj1[xy] ; i++) {
if(b1[kj1[xy][i]] == -1) return(OFF);
}
for(i = 0 ; i < nkj1[xy] ; i++) {
b1[kj1[xy][i]]++;
}
b1[xy] = -1;
return(ON);
}
/* ナイトを取り除く /*
void delKnight(int xy)
{
int i;
for(i = 0 ; i < nkj1[xy] ; i++) {
b1[kj1[xy][i]]--;
}
b1[xy] = 0;
}
/* 鏡像チェック用座標移動データ /*
static int q1[][6] = {
-1, 0, 7, 0, 1, 0 , /* (-x, y) /*
1, 0, 0, 0, -1, 7 , /* ( x,-y) /*
-1, 0, 7, 0, -1, 7 , /* (-x,-y) /*
0, 1, 0, 1, 0, 0 , /* ( y, x) /*
0, -1, 7, 1, 0, 0 , /* (-y, x) /*
0, 1, 0, -1, 0, 7 , /* ( y,-x) /*
0, -1, 7, -1, 0, 7}; /* (-y,-x) /*
/* 鏡像チェック 新規ならon 既存ならoff /*
int check(void)
{
int i , j;
int x , y , x1 ,y1;
static int sb[3][64];
int fDif;
for(i = 0 ; i < count ; i++) {
for(j = 0 ; j < 7 ; j++){
fDif = OFF;
for(y1 = 0 ; y1 < 8 ; y1++) {
for(x1 = 0 ; x1 < 8 ; x1++) {
x = q1[j][0] * x1 + q1[j][1] * y1 + q1[j][2];
y = q1[j][3] * x1 + q1[j][4] * y1 + q1[j][5];
if(b1[pk1[y * 8 + x]] != sb[i][pk1[y1 * 8 + x1]]) {
fDif = ON;
break;
}
}
if(fDif == ON) break;
}
if(fDif == OFF) return(OFF);
}
}
for(i = 0 ; i < 64 ; i++) { /* 新規パターンなら保存する /*
sb[count][i] = b1[i];
}
count++;
return(ON);
}
/* 表示 /*
void disp(void)
{
int i;
printf("========\n");
for(i = 0 ; i < 64 ; i++) {
if(b1[pk1[i]] == -1) printf("o");
else printf("-");
if((i % 8) == 7) printf("\n");
}
}
/* 1目ごとの処理 /*
void sub(int xy , int s , int n)
{
int s1 , xy1;
if(xy == 2) {
if(b1[0] < 0 && b1[1] > 0) return;
}
else if(xy == 3) {
if(b1[0] < 0 && b1[2] > 0) return;
if(b1[1] < 0 && b1[2] > 0) return;
}
else if(xy == 4) {
if(b1[0] < 0 && b1[3] > 0) return;
}
else if(xy == 64) {
if(check() == ON) disp();
return;
}
s1 = s + 1;
if(s1 >= nkj2[xy]) {
s1 = 0;
xy1 = xy + 1;
}
else {
xy1 = xy;
}
if(b1[xy] != 0 || s < nkj2[xy] - 1) {
sub(xy1 , s1 , n);
}
if(nkj2[xy] == 0) return;
if(n == minn1) return;
if(putKnight(kj2[xy][s]) == ON) {
sub(xy1 , s1 , n + 1);
delKnight(kj2[xy][s]);
}
}
/* メイン /*
int main(int argc , char **argv)
{
init();
sub(0 , 0 , 0);
while(count == 0) {
minn1++;
sub(0 , 0 , 0);
}
printf("%d個 %d通り\n" , minn1 , count);
}
|
第116回(11月)三数教室
|
|
#include <stdio.h>
#include <stdlib.h>
#define NN 12
int check(int k , int n , int r1[])
{
int j;
for(j = 0 ; j < n ; j++) {
if(k == r1[j]) return(0);
}
return(1);
}
void print(int p , int r1[])
{
int i;
for(i = 0 ; i < p ; i += 3) {
printf("(%d %d %d)" , r1[i] , r1[i + 1] , r1[i + 2]);
}
printf("\n");
}
int sub2(int n , int s , int z , int r1[])
{
if(z == NN) {
print(z , r1);
return(1);
}
for(r1[z] = r1[z - 3] + 1 ; r1[z] < n ; r1[z]++) {
if(check(r1[z] , z , r1) == 0) continue;
for(r1[z + 1] = r1[z] + 1 ; r1[z + 1] < n ; r1[z + 1]++) {
if(check(r1[z + 1] , z , r1) == 0) continue;
r1[z + 2] = n - r1[z] - r1[z + 1];
if(r1[z + 2] < r1[z + 1]) break;
if(check(r1[z + 2] , z , r1) == 0) continue;
if(z == 0) s = r1[0] * r1[1] * r1[2];
else {
if(r1[z] * r1[z + 1] * r1[z + 2] != s) continue;
}
if(sub2(n , s , z + 3 , r1) == 1) return(1);
}
}
return(0);
}
int main(void)
{
int n = 1;
int r1[NN];
while(sub2(n++ , -1 , 0 , r1) == 0) ;
return(0);
}
|
第115回(10月)ラドクリフの六角陣
|
|
#include <stdio.h>
#define OFF 0
#define ON 1
int a1[19] , b1[20];
int count = 0;
void disp()
{
printf("--------------------\n");
printf(" %2d %2d %2d\n" , a1[0] , a1[1] , a1[2]);
printf(" %2d %2d %2d %2d\n" , a1[3] , a1[4] , a1[5] , a1[6]);
printf("%2d %2d %2d %2d %2d\n" ,
a1[7] , a1[8] , a1[9] , a1[10] , a1[11]);
printf(" %2d %2d %2d %2d\n" , a1[12] , a1[13] , a1[14] , a1[15]);
printf(" %2d %2d %2d\n" , a1[16] , a1[17] , a1[18]);
}
int set3(int c0 , int c1 , int c2 , int flag)
{
if(b1[a1[c2]] == ON && flag == ON) return(OFF);
b1[a1[c2]] = ON;
a1[c1] = 38 - a1[c0] - a1[c2];
if(a1[c1] < 1 || a1[c1] > 19) {
b1[a1[c2]] = OFF;
return(OFF);
}
if(b1[a1[c1]] == ON) {
b1[a1[c2]] = OFF;
return(OFF);
}
b1[a1[c1]] = b1[a1[c2]] = ON;
return(ON);
}
static int d1[] = {4 , 8 , 13 , 5 , 10 , 14};
int set4(int c0 , int c1 , int c2 , int c3 , int n)
{
int i;
a1[c3] = 38 - a1[c0] - a1[c1] - a1[c2];
if(a1[c3] < 1 || a1[c3] > 19) {
for(i = 0 ; i < n ; i++) b1[a1[d1[i]]] = OFF;
return(OFF);
}
if(b1[a1[c3]] == ON) {
for(i = 0 ; i < n ; i++) b1[a1[d1[i]]] = OFF;
return(OFF);
}
b1[a1[c3]] = ON;
return(ON);
}
int set5(int c0 , int c1 , int c2 , int c3 , int c4)
{
int i;
if(a1[c0] + a1[c1] + a1[c2] + a1[c3] + a1[c4] == 38) return(ON);
for(i = 0 ; i < 6 ; i++) b1[a1[d1[i]]] = OFF;
return(OFF);
}
void sub()
{
for(a1[4] = 1 ; a1[4] < 20 ; a1[4]++) {
if(b1[a1[4]] == ON) continue;
b1[a1[4]] = ON;
if(set4(1 , 4 , 12 , 8 , 1) == OFF) continue;
if(set4(3 , 8 , 17 , 13 , 2) == OFF) continue;
if(set4(3 , 4 , 6 , 5 , 3) == OFF) continue;
if(set4(1 , 5 , 15 , 10 , 4) == OFF) continue;
if(set4(6 , 10 , 17 , 14 , 5) == OFF) continue;
a1[9] = 38 - a1[0] - a1[4] - a1[14] - a1[18];
if(a1[9] < 1 || a1[9] > 19) {
b1[a1[4]] = b1[a1[5]] = b1[a1[8]] = b1[a1[10]] = b1[a1[13]] =
b1[a1[14]] = OFF;
continue;
}
if(set5(2 , 5 , 9 , 13 , 16) == OFF) continue;
if(set5(7 , 8 , 9 , 10 , 11) == OFF) continue;
if(a1[12] + a1[13] + a1[14] + a1[15] != 38) {
b1[a1[4]] = b1[a1[5]] = b1[a1[8]] = b1[a1[10]] = b1[a1[13]] =
b1[a1[14]] = OFF;
continue;
}
disp();
count++;
b1[a1[4]] = b1[a1[5]] = b1[a1[8]] = b1[a1[10]] = b1[a1[13]] =
b1[a1[14]] = OFF;
}
}
int main(void)
{
int i;
for(i = 1 ; i < 20 ; i++) b1[i] = OFF;
for(a1[0] = 2 ; a1[0] < 15 ; a1[0]++) {
b1[a1[0]] = ON;
for(a1[2] = a1[0] + 1 ; a1[2] < 20 ; a1[2]++) {
if(set3(0 , 1 , 2 , ON) == OFF) continue;
for(a1[7] = a1[2] + 1 ; a1[7] < 20 ; a1[7]++) {
if(set3(0 , 3 , 7 , ON) == OFF) continue;
for(a1[16] = a1[0] ; a1[16] < 20 ; a1[16]++) {
if(set3(7 , 12 , 16 , ON) == OFF) continue;
for(a1[18] = a1[0] ; a1[18] < 20 ; a1[18]++) {
if(set3(16 , 17 , 18 , ON) == OFF) continue;
for(a1[11] = a1[0] ; a1[11] < 20 ; a1[11]++) {
if(set3(18 , 15 , 11 , ON) == OFF) continue;
if(set3(2 , 6 , 11 , OFF) == OFF) {
b1[a1[11]] = b1[a1[15]] = OFF;
continue;
}
sub();
b1[a1[6]] = b1[a1[11]] = b1[a1[15]] = OFF;
}
b1[a1[17]] = b1[a1[18]] = OFF;
}
b1[a1[12]] = b1[a1[16]] = OFF;
}
b1[a1[3]] = b1[a1[7]] = OFF;
}
b1[a1[1]] = b1[a1[2]] = OFF;
}
b1[a1[0]] = OFF;
}
printf("--------------------\n");
printf("%d通り\n" , count);
return(0);
}
|
第114回(9月)循環する数列
|
|
#include <stdio.h>
#include <stdlib.h>
/* 数字を降順に並べ替える /*
int func(int n , int h)
{
int d[10]; /* 構成する数字の個数 /*
int i , j = 9;
int s = 0;
for(i = 0 ; i < 10 ; i++) d[i] = 0;
for(i = 0 ; i < h ; i++) {
d[n % 10]++;
n /= 10;
}
for(i = 0 ; i < h ; i++) {
while(d[j] == 0) j--;
s = s * 10 + j;
d[j]--;
}
return(s);
}
int main(void)
{
int i , j , k; /* カウンタ /*
int count; /* 循環数 /*
int a0 , a1; /* an , an+1 /*
int r1[10000]; /* 履歴 /*
int j0 = 1 , j1 = 9; /* 各桁における開始、終了の数 /*
for(i = 1 ; i < 10 ; i++) {
for(j = j0 ; j < j1 ; j++) {
a0 = j;
r1[0] = a0;
count = 1;
while(1) {
a1 = func(a0 , i) - a0;
if(a1 < j0) break;
if(a1 == j) {
if(count > 9) {
printf("%d %d\n" , j , count);
return(1);
}
}
for(k = 0 ; k < count ; k++) {
if(a1 == r1[k]) break;
}
if(k < count) break;
a0 = a1;
r1[count++] = a0;
}
}
j0 += j1;
j1 *= 10;
}
return(0);
}
|
第113回(8月)ボールピラミッド
|
|
#include <stdio.h>
#define OFF 0
#define ON 1
int count = 0;
int c0[5][60][4]; /* 各ピースを置くすべての組み合わせ /*
int rn[5]; /* ピースごとの置ける通りの数 /*
int d1[5] = {4 , 4 , 3 , 3 , 2}; /* ピースを更生するボールの数 /*
/* 初期化処理 /*
void init(int b1[])
{
int i , j , k , l;
/* ピースの定義 /*
static int a0[] = {0,4,7,9 , 3,12,17,19};
static int a1[] = {1,5,8,13 , 5,10,13,15 , 6,11,14,18 , 2,11,14,16};
static int a2[] = {1,5,8,15};
static int a3[] = {0,4,7 , 4,7,9, 1,5,8 , 10,13,15, 6,14,18 , 2,11,16 ,
3,12,17 , 12,17,19};
static int a4[] = {1,5,13 , 5,13,10 , 13,10,1 , 10,1,5 , 5,8,15 , 8,15,13 ,
15,13,5 , 13,5,8 , 6,14,11 , 14,11,2 , 11,2,6 , 2,6,14 , 14,18,16 ,
18,16,11 , 16,11,14 , 11,14,18};
static int a5[] = { 0,4 , 4,7, 7,9 , 1,5 , 5,8 , 10,13 , 13,15 , 1,10 ,
5,13 , 8,15 , 6,14 , 14,18 , 2,11 , 11,16 , 2,6 , 11,14 , 16,18 ,
3,12 , 12,17 , 17,19};
static int *g1[] = {a0 , a1 , a3 , a4 , a5};
/* 3方向の定義 /*
static int e1[3][20] = {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
9,7,4,0,8,5,1,6,2,3,15,13,10,14,11,12,18,16,17,19,
3,6,8,9,2,5,7,1,4,0,12,14,15,11,13,10,17,18,16,19};
static int f1[5] = {2 , 4 , 8 , 16 , 20};
for(i = 0 ; i < 5 ; i++) {
rn[i] = 0;
for(j = 0 ; j < f1[i] ; j++) {
for(k = 0 ; k < 3 ; k++) {
for(l = 0 ; l < d1[i] ; l++) {
c0[i][rn[i]][l] = e1[k][*(g1[i] + j * d1[i] + l)];
if(c0[i][rn[i]][l] == a2[0]) break;
if(c0[i][rn[i]][l] == a2[1]) break;
if(c0[i][rn[i]][l] == a2[2]) break;
if(c0[i][rn[i]][l] == a2[3]) break;
}
if(l == d1[i]) rn[i]++;
}
}
}
for(i = 0 ; i < 20 ; i++) b1[i] = OFF;
}
void sub(int b1[] , int n)
{
int i , j;
for(i = 0 ; i < rn[n] ; i++) {
/* 置けるかどうかのチェック /*
if(b1[c0[n][i][0]] == ON) continue;
if(b1[c0[n][i][1]] == ON) continue;
if(d1[n] > 2 && b1[c0[n][i][2]] == ON) continue;
if(d1[n] == 4 && b1[c0[n][i][3]] == ON) continue;
for(j = 0 ; j < d1[n] ; j++) b1[c0[n][i][j]] = ON;
/* 6ピース全部置けたときはカウントアップする /*
if(n == 4) count++;
else sub(b1 , n + 1);
for(j = 0 ; j < d1[n] ; j++) b1[c0[n][i][j]] = OFF;
}
}
int main(void)
{
int b1[20];
init(b1);
sub(b1 , 0);
printf("%d\n" , count);
return(0);
}
|
第112回(7月)Fペントミノ
|
|
#include <stdio.h>
#define OFF 0
#define ON 1
typedef struct {
int x;
int y;
} XY;
XY pent[8][4];
static XY pent1[4] = {0 , -1 , -1 , 0 , 0 , 1 , 1 , 1};
static XY dxy[8][2] = {1,0,0,1 , -1,0,0,1 , 1,0,0,-1 , -1,0,0,-1 ,
0,1,1,0 , 0,-1,1,0 , 0,1,-1,0 , 0,-1,-1,0};
static int max = -1;
static int count = 0;
int b1[8][8];
void init()
{
int i , j;
for(i = 0 ; i < 8 ; i++) {
for(j = 0 ; j < 4 ; j++) {
pent[i][j].x = pent1[j].x * dxy[i][0].x +
pent1[j].y * dxy[i][0].y;
pent[i][j].y = pent1[j].x * dxy[i][1].x +
pent1[j].y * dxy[i][1].y;
}
for(j = 0 ; j < 8 ; j++) b1[i][j] = OFF;
}
}
int check(int x , int y)
{
int i , j;
if(y < 1) return(OFF);
if(x < 1) return(OFF);
if(b1[y][x] == ON) return(OFF);
for(i = 0 ; i < 8 ; i++) {
for(j = 0 ; j < 4 ; j++) {
if(b1[y + dxy[i][j].y][x + dxy[i][j].y] == ON) break;
}
if(j == 4) return(ON);
}
if(x != 5) return(OFF);
x = 6;
if(b1[y][x] == ON) return(OFF);
for(i = 0 ; i < 8 ; i++) {
for(j = 0 ; j < 4 ; j++) {
if(b1[y + dxy[i][j].y][x + dxy[i][j].y] == ON) break;
}
if(j == 4) return(ON);
}
return(OFF);
}
void sub(int x , int y , int ko)
{
int i , j;
int x1 , y1;
if(y == 7) {
if(ko > max) {
max = ko;
count = 1;
}
else if(ko == max) {
count++;
}
return;
}
if(check(x - 2 , y - 2) == ON) return;
x1 = x + 1;
y1 = y;
if(x1 == 7) {
x1 = 1;
y1++;
}
sub(x1 , y1 , ko);
if(b1[y][x] == ON) {
return;
}
for(i = 0 ; i < 8 ; i++) {
for(j = 0 ; j < 4 ; j++) {
if(b1[y + pent[i][j].y][x + pent[i][j].x] == ON) break;
}
if(j < 4 ) continue;
b1[y][x] = ON;
for(j = 0 ; j < 4 ; j++) {
b1[y + pent[i][j].y][x + pent[i][j].x] = ON;
}
sub(x1 , y1 , ko + 1);
b1[y][x] = OFF;
for(j = 0 ; j < 4 ; j++) {
b1[y + pent[i][j].y][x + pent[i][j].x] = OFF;
}
}
}
int main(void)
{
init();
sub(1 , 1 , 0);
printf("%d %d\n" , max , count / 8);
return(0);
}
|
第111回(6月)パズルペンシルスタンド
|
|
#include <stdio.h>
#define OFF 0
#define ON 1
typedef struct {
int x;
int y;
} XY;
XY pent[8][4];
static XY pent1[4] = {0 , -1 , -1 , 0 , 0 , 1 , 1 , 1};
static XY dxy[8][2] = {1,0,0,1 , -1,0,0,1 , 1,0,0,-1 , -1,0,0,-1 ,
0,1,1,0 , 0,-1,1,0 , 0,1,-1,0 , 0,-1,-1,0};
static int max = -1;
static int count = 0;
int b1[8][8];
void init()
{
int i , j;
for(i = 0 ; i < 8 ; i++) {
for(j = 0 ; j < 4 ; j++) {
pent[i][j].x = pent1[j].x * dxy[i][0].x +
pent1[j].y * dxy[i][0].y;
pent[i][j].y = pent1[j].x * dxy[i][1].x +
pent1[j].y * dxy[i][1].y;
}
for(j = 0 ; j < 8 ; j++) b1[i][j] = OFF;
}
}
int check(int x , int y)
{
int i , j;
if(y < 1) return(OFF);
if(x < 1) return(OFF);
if(b1[y][x] == ON) return(OFF);
for(i = 0 ; i < 8 ; i++) {
for(j = 0 ; j < 4 ; j++) {
if(b1[y + dxy[i][j].y][x + dxy[i][j].y] == ON) break;
}
if(j == 4) return(ON);
}
if(x != 5) return(OFF);
x = 6;
if(b1[y][x] == ON) return(OFF);
for(i = 0 ; i < 8 ; i++) {
for(j = 0 ; j < 4 ; j++) {
if(b1[y + dxy[i][j].y][x + dxy[i][j].y] == ON) break;
}
if(j == 4) return(ON);
}
return(OFF);
}
void sub(int x , int y , int ko)
{
int i , j;
int x1 , y1;
if(y == 7) {
if(ko > max) {
max = ko;
count = 1;
}
else if(ko == max) {
count++;
}
return;
}
if(check(x - 2 , y - 2) == ON) return;
x1 = x + 1;
y1 = y;
if(x1 == 7) {
x1 = 1;
y1++;
}
sub(x1 , y1 , ko);
if(b1[y][x] == ON) {
return;
}
for(i = 0 ; i < 8 ; i++) {
for(j = 0 ; j < 4 ; j++) {
if(b1[y + pent[i][j].y][x + pent[i][j].x] == ON) break;
}
if(j < 4 ) continue;
b1[y][x] = ON;
for(j = 0 ; j < 4 ; j++) {
b1[y + pent[i][j].y][x + pent[i][j].x] = ON;
}
sub(x1 , y1 , ko + 1);
b1[y][x] = OFF;
for(j = 0 ; j < 4 ; j++) {
b1[y + pent[i][j].y][x + pent[i][j].x] = OFF;
}
}
}
int main(void)
{
init();
sub(1 , 1 , 0);
printf("%d %d\n" , max , count / 8);
return(0);
}
|
第110回(5月)欲張りな2数
|
|
#include <stdio.h>
#define OFF 0
#define ON 1
int s1[80000];
int ns1 = 0;
int r1[9];
void init(void)
{
int i , j;
int w1[90000];
for(i = 1 ; i < 90000 ; i++) w1[i] = ON;
for(i = 2 ; i < 300 ; i++) {
if(w1[i] == OFF) continue;
for(j = i * 2 ; j < 90000 ; j += i) w1[j] = OFF;
}
for(i = 2 ; i < 80000 ; i++) {
if(w1[i] == ON) s1[ns1++] = i;
}
r1[0] = 1;
for(i = 1 ; i < 9 ; i++) r1[i] = r1[i - 1] * 10;
}
int check(int t)
{
int ch[10];
int i;
int n;
for(i = 1 ; i < 10 ; i++) ch[i] = OFF;
for(i = 0 ; i < 9 ; i++) {
n = (t / r1[i]) % 10;
if(n == 0 || ch[n] == ON) return(OFF);
ch[n] = ON;
}
return(ON);
}
void sub(int a , int b)
{
int t;
int bb;
bb = 987654321 / a;
if(b > bb + 1) return;
t = a * b;
if(t > 987654321) return;
if(check(t) == OFF) return;
printf("%d %d\n" , a , b);
}
int main(void)
{
int i , j;
int a , b;
int s;
init();
for(i = 142 ; i < 448 ; i += 2) {
a = i * i / 2 + 1;
b = a - 2;
sub(a , b);
}
for(i = 143 ; i < 448 ; i += 2) {
s = i * i;
for(j = 1 ; j < ns1 ; j++) {
b = s - s1[j];
if(b < 20000) break;
b /= 2;
a = b + s1[j];
if(a > 99999) continue;
sub(a , b);
}
}
return(0);
}
|
第109回(4月)クロススクエアドナンバーパズル
|
|
#include <stdio.h>
#define OFF 0
#define ON 1
#define YOKO 0
#define TATE 1
#define N1 6
#define N2 16
static char *p1[N1] = {
"ooooxo" ,
"ooxooo" ,
"ooooox" ,
"xooooo" ,
"oooxoo" ,
"oxoooo"};
int p2[N1][N1];
typedef struct {
int n; /* 平方数 /*
int d[6]; /* 平方数の各桁の値 /*
int f; /* 使用済みフラグ /*
} A1;
static A1 a1[1000];
static int b1[] = {0 , 1 , 4 , 10 , 32 , 100 , 317 , 1000};
int b2[7][10][2];
typedef struct {
int x; /* 始点X座標 /*
int y; /* 始点Y座標 /*
int h; /* 方向 /*
int l; /* 長さ /*
} C1;
C1 c1[N2];
int d1[N2];
int z1[N2];
int z2[N2][5][3]; /* 交差チェック用 /*
int t[N2];
int nc1 = 0;
void disp()
{
int i , j;
int x , y;
int g1[N1][N1];
for(y = 0 ; y < N1 ; y++) {
for(x = 0 ; x < N1 ; x++) g1[y][x] = -1;
}
for(i = 0 ; i < N2 ; i++) {
for(j = 0 ; j < c1[i].l ; j++) {
x = c1[i].x + j * (1 - c1[i].h);
y = c1[i].y + j * c1[i].h;
g1[y][x] = a1[d1[i]].d[j];
}
}
for(y = 0 ; y < N1 ; y++) {
for(x = 0 ; x < N1 ; x++) {
if(g1[y][x] == -1) printf("x");
else printf("%d" , g1[y][x]);
}
printf("\n");
}
}
/* 初期化 (横方向) /*
void sub1(int x , int y)
{
int i , l = 1;
if(x > 0) {
if(p2[y][x - 1] == 0) return;
}
for(i = x + 1 ; i < N1 ; i++) {
if(p2[y][i] == 1) break;
l++;
}
if(l == 1) return;
c1[nc1].x = x;
c1[nc1].y = y;
c1[nc1].h = YOKO;
c1[nc1++].l = l;
}
/* 初期化 (縦方向) /*
void sub2(int x , int y)
{
int i , l = 1;
if(y > 0) {
if(p2[y - 1][x] == 0) return;
}
for(i = y + 1 ; i < N1 ; i++) {
if(p2[i][x] == 1) break;
l++;
}
if(l == 1) return;
c1[nc1].x = x;
c1[nc1].y = y;
c1[nc1].h = TATE;
c1[nc1++].l = l;
}
/* 初期化 /*
void init()
{
int i , j , l;
int x , y;
int w1[N1][N1] , w2[N1][N1];
int a;
for(y = 0 ; y < N1 ; y++) {
for(x = 0 ; x < N1 ; x++) {
if(*(p1[y] + x) == 'o') p2[y][x] = 0;
else p2[y][x] = 1;
}
}
for(y = 0 ; y < N1 ; y++) {
for(x = 0 ; x < N1 ; x++) {
if(p2[y][x] == 1) continue;
if(x < N1 - 1) sub1(x , y);
if(y < N1 - 1) sub2(x , y);
}
}
for(i = 2 ; i < 7 ; i++) {
for(j = 1 ; j < 10 ; j++) {
b2[i][j][0] = 100000;
b2[i][j][1] = -100000;
}
}
for(i = 4 ; i < b1[7] ; i++) {
a = a1[i].n = i * i;
l = 6;
while(a < 100000) {
a *= 10;
l--;
}
a1[i].d[0] = a / 100000;
a1[i].d[1] = (a / 10000) % 10;
a1[i].d[2] = (a / 1000) % 10;
a1[i].d[3] = (a / 100) % 10;
a1[i].d[4] = (a / 10) % 10;
a1[i].d[5] = a % 10;
a1[i].f = OFF;
if(i < b2[l][a1[i].d[0]][0]) b2[l][a1[i].d[0]][0] = i;
if(i > b2[l][a1[i].d[0]][1]) b2[l][a1[i].d[0]][1] = i;
}
for(i = 0 ; i < N1 ; i++) {
for(j = 0 ; j < N1 ; j++) w1[i][j] = -1;
}
for(i = 0 ; i < N2 ; i++) {
z1[i] = 0;
for(j = 0 ; j < c1[i].l ; j++) {
x = c1[i].x + j * (TATE - c1[i].h);
y = c1[i].y + j * c1[i].h;
if(w1[y][x] == -1) {
w1[y][x] = i;
w2[y][x] = j;
}
else {
z2[i][z1[i]][0] = w1[y][x];
z2[i][z1[i]][1] = w2[y][x];
z2[i][z1[i]][2] = j;
z1[i]++;
}
}
}
}
/* 再帰呼びだし関数 /*
void sub(int n)
{
int i , j;
int f;
int e , s;
if(n == N2) {
disp();
return;
}
if(z1[n] > 0 && z2[n][0][2] == 0) {
if(a1[d1[z2[n][0][0]]].d[z2[n][0][1]] == 0) return;
s = b2[c1[n].l][a1[d1[z2[n][0][0]]].d[z2[n][0][1]]][0];
e = b2[c1[n].l][a1[d1[z2[n][0][0]]].d[z2[n][0][1]]][1] + 1;
}
else {
s = b1[c1[n].l];
e = b1[c1[n].l + 1];
}
for(i = s ; i < e ; i++) {
if(a1[i].f == ON) continue;
f = OFF;
for(j = 0 ; j < z1[n] ; j++) {
if(a1[d1[z2[n][j][0]]].d[z2[n][j][1]] != a1[i].d[z2[n][j][2]]) {
f = ON;
break;
}
}
if(f == ON) continue;
a1[i].f = ON;
d1[n] = i;
sub(n + 1);
a1[i].f = OFF;
}
}
int main(void)
{
init();
sub(0);
return(0);
}
|
第108回(3月)最後の聖銭
|
|
/* C MAGAZINE 1999.12 電脳クラブ /*
#include <stdio.h>
#include <stdlib.h>
#define SS 2 /* 聖数の初期値 /*
#define N0 0 /* 硬貨の位置の初期値 /*
#define N12 12 /* 500円玉の位置 /*
#define N17 17 /* 手数 /*
#define N18 18 /* 硬貨の数 /*
#define A0 0 /* 硬貨なし /*
#define A1 1 /* 硬貨あり /*
#define A2 2 /* 500円玉あり /*
#define J1 1 /* 移動する際の初期値 /*
int main(void)
{
int i; /* 手数カウンタ /*
int j; /* 移動用カウンタ /*
int m; /* 現在地 /*
int n = SS; /* 聖数 /*
int b1[N18]; /* 硬貨の状態 /*
/* 聖数が見つかるまでループする /*
while(1) {
m = N0;
for(i = 0 ; i < N18 ; i++) b1[i] = A1;
b1[N12] = A2;
/* 17手繰り返す /*
for(i = 0 ; i < N17 ; i++) {
/* 聖数分、動く /*
j = J1;
while(j != n) {
m++;
if(m == N18) m = N0;
if(b1[m] != A0) j++;
}
/* 500円玉だったら抜ける /*
if(b1[m] == A2) {
b1[m] = A1;
break;
}
b1[m] = A0;
/* 硬貨が取り除かれていないところまで移動する /*
while(b1[m] == A0) {
m++;
if(m == N18) m = N0;
}
}
/* 最後に残った硬貨が500円玉なら抜ける /*
if(b1[m] == A1) n++;
else break;
}
/* 解答を表示する /*
printf("%d\n" , n);
return(0);
}
|
第107回(2月)Hoppers
|
|
#include <stdio.h>
#include <stdlib.h>
#define OFF 0
#define ON 1
static int d1[16][3] = {
0 , 1 , 2 , 0 , 3 , 6 , 0 , 5 , 10 , 1 , 3 , 5 ,
1 , 6 ,11 , 1 , 4 , 7 , 2 , 4 , 6 , 2 , 7 , 12 ,
3 , 6 , 9 , 4 , 6 , 8 , 5 , 6 , 7 , 5 , 8 , 11 ,
6 , 8 ,10 , 6 , 9 , 12 , 7 , 9 , 12 , 10 , 11 , 12};
static int b1[13] = {ON , ON , ON , ON , ON , ON , OFF , ON , ON , ON ,
ON , ON , ON};
int min = 13;
int e1[11];
int z1[100][11];
int nz = 0;
void sub(int n , int y , int m)
{
int i , j;
int f0 , f1 , f2;
if(m == 11 && b1[6] == ON) {
if(n < min) {
min = n;
nz = 0;
}
if(n == min) {
for(i = 0 ; i < 11 ; i++) z1[nz][i] = e1[i];
nz++;
}
return;
}
for(i = 0 ; i < 16 ; i++) {
for(j = 0 ; j < 3 ; j += 2) {
f0 = d1[i][j];
if(n == 0 && f0 != 0) continue;
if(n == 2 && f0 == 10) continue;
if(b1[f0] == OFF) continue;
f1 = d1[i][1];
if(b1[f1] == OFF) continue;
f2 = d1[i][2 - j];
if(b1[f2] == ON) continue;
b1[f0] = OFF;
b1[f1] = OFF;
b1[f2] = ON;
e1[m] = f0 + f2 * 13;
sub(n + (y == f0 ? 0 : 1) , f2 , m + 1);
b1[f0] = ON;
b1[f1] = ON;
b1[f2] = OFF;
}
}
}
int main(void)
{
int i , j;
sub(0 , -1 , 0);
printf("最小手:%d\n" , min);
for(i = 0 ; i < nz ; i++) {
for(j = 0 ; j < 11 ; j++) {
printf("(%c %c)" ,
(char)('A' + z1[i][j] % 13) , (char)('A' + z1[i][j] / 13));
}
printf("\n");
}
return(0);
}
|
第106回(1月)楊貴妃問題
|
|
#include <stdio.h>
#include <stdlib.h>
int r1[950][2];
int r2[950][2];
int r3[50][19];
int min;
void sub(int a0[] , int n)
{
int i;
int a1[3];
int t1 , t2;
static int d[][3] = {0,1,2 , 0,2,1 , 1,0,2 , 1,2,0 , 2,0,1 , 2,1,0};
static int max[] = {88 , 49 , 18};
if(r3[a0[1]][a0[2]] < n) return;
r3[a0[1]][a0[2]] = n;
r1[n][0] = a0[1];
r1[n++][1] = a0[2];
if(a0[1] == 0 && a0[2] == 9) {
for(i = 0 ; i < n ; i++) {
r2[i][0] = r1[i][0];
r2[i][1] = r1[i][1];
}
min = n;
return;
}
for(i = 0 ; i < 6 ; i++) {
t1 = max[d[i][0]] - a0[d[i][0]];
t2 = t1 < a0[d[i][1]] ? t1 : a0[d[i][1]];
a1[d[i][0]] = a0[d[i][0]] + t2;
a1[d[i][1]] = a0[d[i][1]] - t2;
a1[d[i][2]] = a0[d[i][2]];
sub(a1 , n);
}
}
int main(void)
{
int i , j;
static int a0[3] = {88 , 0 , 0};
for(i = 0 ; i < 50 ; i++) {
for(j = 0 ; j < 19 ; j++) r3[i][j] = 950;
}
sub(a0 , 0);
for(i = 0 ; i < min ; i++) {
printf("(%2d,%2d,%2d)\n" ,
88 - r2[i][0] - r2[i][1] , r2[i][0] , r2[i][1]);
}
return(0);
}
| | | | | | | | | | | |