HBUOJ--素数幻方

HBUOJ–素数幻方
求四阶的素数幻方。即在一个4*4的矩阵中,每一个格填入一个数字,使每一行、每一列和两条对角线上的四个数字所组成的四位数, 均为可逆素数。
【可逆素数:将某一素数的各位数字的顺序颠倒后得到的数仍是素数】
**输入格式要求:"%d" 提示信息:“There are magic aquares with invertable primes as follow:\n”
**输出格式要求:“No.%d\n” “%6d”
程序运行示例如下:
There are magic aquares with invertable primes as follow:
No.1
1 1 9 3
1 0 0 9
9 2 2 1
3 1 9 1
No.2
1 1 9 3
1 0 2 1
9 0 2 9
3 9 1 1

我只不过是打开了一道极难,然后我傻了…
再也不瞎选难度惹…先贴上答案…
゜ー゜

#include <math.h>
#include <stdio.h>
int number[210][5];
int select [110];
int array[4][5];
int count;
int selecount;
int larray[2][200];
int lcount[2];
main()
{             
    int i, k, flag, cc = 0, i1, i4;
    printf("There are magic aquares with invertable primes as follow:\n");
    for (i = 1001; i < 9999; i += 2)
    {             
        k = i / 1000;
        if (k % 2 != 0 && k != 5 && num(i))
        {             
            number[count][0] = i;
            process(count++);
            if (number[count - 1][2] % 2 != 0 && number[count - 1][3] % 2 != 0
                    && number[count - 1][2] != 5 && number[count - 1][3] != 5)
                select[selecount++] = count - 1;
        }
    }
    larray[0][lcount[0]++] = number[0][0] / 100;
    larray[1][lcount[1]++] = number[0][0] / 10;
    for (i = 1; i < count; i++)
    {             
        if (larray[0][lcount[0] - 1] != number[i][0] / 100)
            larray[0][lcount[0]++] = number[i][0] / 100;
        if (larray[1][lcount[1] - 1] != number[i][0] / 10)
            larray[1][lcount[1]++] = number[i][0] / 10;
    }
    for (i1 = 0; i1 < selecount; i1++)
    {             
        array[0][0] = select[i1];
        copy_num(0);
        for (array[1][0] = 0; array[1][0] < count; array[1][0]++)
        {             
            copy_num(1);
            if (!comp_num(2))
                continue;
            for (array[2][0] = 0; array[2][0] < count; array[2][0]++)
            {             
                copy_num(2);
                if (!comp_num(3))
                    continue;
                for (i4 = 0; i4 < selecount; i4++)
                {             
                    array[3][0] = select[i4];
                    copy_num(3);
                    for (flag = 1, i = 1; flag && i <= 4; i++)
                        if (!find1(i)) flag = 0;
                    if (flag && find2())
                    {             
                        printf("No.%d\n", ++cc);
                        p_array();
                    }
                }
            }
 
        }
 
    }
}             
num(int number)
{             
    int j;
    if (!ok(number)) return(0);
    for (j = 0; number > 0; number /= 10)
        j = j * 10 + number % 10;
    if (!ok(j)) return(0);
    return(1);
}             
ok (int number)
{             
    int i, j;
    if (number % 2 == 0) return(0);
    j = sqrt((double)number) + 1;
    for (i = 3; i <= j; i += 2)
        if (number % i == 0)return(0);
    return(1);
}             
process(int i)
{             
    int j, num;
    num = number[i][0];
    for (j = 4; j >= 1; j--, num /= 10)
        number[i][j] = num % 10;
}             
copy_num(int i)
{             
    int j;
    for (j = 1; j <= 4; j++)
        array[i][j] = number[array[i][0]][j];
}             
comp_num (int n)
{             
    static int ii;
    static int jj;
    int i, num, k, *p;
    int *pcount;
    switch (n)
    {             
    case 2:
        pcount = &lcount[0];
        p = &ii;
            break;
    case 3:
        pcount = &lcount[1];
        p = &jj;
        break;
    default:
        return(0);
    }
    for (i = 1; i <= 4; i++)
    {             
        for (num = 0, k = 0; k < n; k++)
            num = num * 10 + array[k][i];
        if ( num <= larray[n - 2][*p] )
            for (; *p >= 0 && num < larray[n - 2][*p]; (*p)--)
                ;
        else
            for (; *p < *pcount && num > larray[n - 2][*p]; (*p)++);
        if ( *p < 0 || *p >= *pcount )
        {             
            *p = 0;
            return(0);
        }
        if ( num != larray[n - 2][*p] )
            return(0);
 
    }
    return(1);
}             
find1 (int i)
{             
    int num, j;
    for (num = 0, j = 0; j < 4; j++ )
        num = num * 10 + array[j][i];
    return (find0(num));
}             
find2(void)
{             
    int num1, num2, j, i;
    for (num1 = 0, j = 0; j < 4; j++)
        num1 = num1 * 10 + array[j][j + 1];
    for (num2 = 0, j = 0, i = 4; j < 4; j++, i--)
        num2 = num2 * 10 + array[j][i];
    if (find0(num1))
        return(find0(num2));
    else return(0);
}             
find0 (int num)
{             
    static int j;
    if (num <= number[j][0])
        for (; j >= 0 && num < number[j][0]; j--);
    else
        for (; j < count && num > number[j][0]; j++);
    if (j < 0 || j >= count)
    {             
        j = 0;
        return(0);
    }
    if (num == number[j][0])
        return(1);
    else return(0);
}             
p_array(void)
{             
    int i, j;
    for (i = 0; i < 4; i++)
    {             
        for (j = 1; j <= 4; j++)
            printf("%6d", array[i][j]);
        printf("\n");
 
    }
}           
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值