横丁の名探偵

トップ > Cマガ電脳クラブ挑戦記録の部屋(過去) > Cマガ電脳クラブソースリスト(2000年分)



第117回(12月)オールナイトパズル

#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);
}