100個經典C語言程式(益智類)
100個經典C語言程式(益智類)
【1.繪製餘弦曲線】
在螢幕上用“*”顯示0~360度的餘弦函式cos(x)曲線
[問題分析與演算法設計] 利用cos(x)的左右對稱性,將螢幕的行方向定義為x,列方向定義為y,則0~180度的圖形與180~360度的圖形是左右對稱的,若定義圖形的總寬度為62列,計算出x行0~180度時y點的座標m,那麼在同一行與之對稱的180~360度的y點的座標就 應為62-m。程式中利用反餘弦函式acos計算座標(x,y)的對應關係。
#include<stdio.h>
#include<math.h>
void main(){
double y;
int x,m;
for(y=1;y>=-1;y-=0.1){
m=acos(y)*10;
for(x=1;x<m;x++)
printf(" ");
printf("*");
for(;x<62-m;x++)
printf(" ");
printf("*");
printf("\n");
}
}
【2.繪製餘弦曲線和直線】
在螢幕上顯示0~360度的cos(x)曲線與直線f(x)=45*(y-1)+31的迭加圖形。其中cos(x)圖形用“*”表示,f(x)用“+”表示,在兩個圖形相交的點上則用f(x)圖形的符號。
[問題分析與演算法設計] 圖形迭加的關鍵是要在分別計算出同一行中兩個圖形的列方向點座標後,正確判斷相互的位置關係。為此,可以先判斷圖形的交點,再分別控制列印兩個不同的圖形。
#include<stdio.h>
#include<math.h>
void main(){
double y;
int x,m,n,yy;
for(yy=0;yy<=20;yy++){
y=0.1*yy;
m=acos(1-y)*10;
n=45*(y-1)+31;
for(x=0;x<62;x++){
if(x==m&&x==n)
printf("+");
else if(x==n)
printf("+");
else if(x==m||x==62-m)
printf("*");
else
printf(" ");
}
printf("\n");
}
}
【3.繪製圓】
在螢幕上用“*”畫一個空心的圓
[演算法分析與設計] 列印圓可利用圖形的左右對稱性。根據圓的方程:R*R=X*X+Y*Y 可以算出圓上每一點行和列的對應關係。
#include<stdio.h>
#include<math.h>
void main(){
double y;
int x,m;
for(y=10;y>=-10;y--){
m=2.5*sqrt(100-y*y);
for(x=1;x<30-m;x++)
printf(" ");
printf("*");
for(;x<30+m;x++)
printf(" ");
printf("*\n");
}
}
【4.歌星大獎賽】
在歌星大獎賽中,有10個評委為參賽的選手打分,分數為1~100分。
[演算法分析與設計]選手最後得分為:去掉一個最高分和一個最低分後其餘8個分數的平均值。請編寫一個程式實現。
#include<stdio.h>
void main(){
int integer,i,max,min,sum;
max=-32768;
min=32767;
sum=0;
for(i=1;i<=10;i++){
printf("Input number %d = ",i);
scanf("%d",&integer);
sum+=integer;
if(integer>max)
max=integer;
if(integer<min)
min=integer;
}
printf("\nCanceled max score:%d\nCanceled min score:%d\n",max,min);
printf("\nAverage score: %d\n",(sum-max-min)/8);
}
【5.求最大數】
問555555的約數中最大的三位數是多少?
#include<stdio.h>
void main(){
long i;
int j;
printf("Please input the number: ");
scanf("%ld",&i);
for(j=999;j>=100;j--){
if(i%j==0){
printf("The max factor with 3 digits in %ld is: %d\n",i,j);
break;
}
}
}
【6.高次方數的尾數】
求13的13次方的最後三位數
[演算法設計與分析]研究乘法的規律發現:乘積的最後三位的值只與乘數和被乘數的後三位有關,與乘數和被乘數的高位無關。
#include<stdio.h>
void main(){
int i,x,y,last=1;
printf("Input X and Y(X**Y):");
scanf("%d**%d",&x,&y);
for(i=1;i<=y;i++)
last=last*x%1000;
printf("The last 3 digits of %d**%d is:%d\n",x,y,last%1000);
}
【7. 分數四則運算】
對輸入的兩個分數進行+、-、*、/四則運算,輸出分數結果。
#include<stdio.h>
void main(){
long int a,b,c,d,i,x,y,z;
char op;
printf("兩分數b/a,d/c作+,-,*,/四則運算,結果為分數。\n");
printf("請輸入分數運算式。\n");
scanf("%ld/%ld%c%ld/%ld",&b,&a,&op,&d,&c);
if(a==0||c==0) {
printf("分母為0輸入錯誤!");
}
if(op=='+') {
y=b*c+d*a;
x=a*c;
}
if(op=='-') {
y=b*c-d*a;
x=a*c;
}
if(op=='*') {
y=b*d;
x=a*c;
}
if(op=='/') {
y=b/c;
x=a/d;
}
z=x;
if(x>y)
z=y;
i=z;
while(i>1) {
if(x%i==0&&y%i==0){
x=x/i;
y=y/i;
continue;
}
i--;
}
printf("%ld/%ld%c%ld/%ld=%ld/%ld.\n",b,a,op,d,c,y,x);
}
【8.借書方案知多少】
小明有五本新書,要借給A,B,C三位小朋友,若每人每次只能借一本,則可以有多少種不同的借法?
#include<stdio.h>
void main(){
int a,b,c,count=0;
printf("There are diffrent methods for XM to distribute books to 3 readers:\n");
for(a=1;a<=5;a++)
for(b=1;b<=5;b++)
for(c=1;c<=5;c++)
if(a!=b&&c!=a&&c!=b)
printf(count%8?"%2d:%d,%d,%d ":"%2d:%d,%d,%d \n",++count,a,b,c);
}
【9.楊輝三角形】
在螢幕上顯示楊輝三角形
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
#include<stdio.h>
int c(int x,int y){
int z;
if((y==1)||(y==x+1))
return 1;
z=c(x-1,y-1)+c(x-1,y);
return z;
}
void main(){
int i,j,n=13;
printf("N=");
while(n>12)
scanf("%d",&n);
for(i=0;i<=n;i++){
for(j=0;j<24-2*i;j++)
printf(" ");
for(j=1;j<i+2;j++)
printf("%4d",c(i,j));
printf("\n");
}
}
【10.數制轉換】
將任一整數轉換為二進位制形式
#include<stdio.h>
void printb(int x,int n){
if(n>0){
putchar(\'0\'+((unsigned)(x&(1<<(n-1)))>>(n-1)));
printb(x,n-1);
}
}
void main(){
int x;printf("Input number:");
scanf("%d",&x);
printf("number of decimal form:%d\n",x);
printf(" it\'s binary form:");
printb(x,sizeof(int)*8);
putchar(\'\n\');
}
【11.打魚還是晒網】
中國有句俗語叫“三天打魚兩天晒網”。某人從1990年1月1日起開始“三天打魚兩天晒網”,問這個人在以後的某一天中是“打魚”還是“晒網”。
#include<stdio.h>
struct date{
int year;
int month;
int day;
};
int days(struct date day){
static int day_tab[2][13]=
{{0,31,28,31,30,31,30,31,31,30,31,30,31}, {0,31,29,31,30,31,30,31,31,30,31,30,31}};
int i,lp;
lp=(day.year%4==0)&&(day.year%100!=0)||(day.year%400==0); //判定year為閏年還是平年,lp=0為平年,非0為閏年
for(i=1;i<day.month;i++){ //計算本年中自1月1日起的天數
if(lp=0)
day.day+=day_tab[0][13];
else
day.day+=day_tab[1][13];
}
return day.day;
}
void main(){
struct date today,term;
int yearday,year,day;
printf("Enter year/month/day:");
scanf("%d%d%d",&today.year,&today.month,&today.day); /*輸入日期*/
term.month=12; /*設定變數的初始值:月*/
term.day=31; /*設定變數的初始值:日*/
for(yearday=0,year=1990;year<today.year;year++){
term.year=year;
yearday+=days(term); /*計算從1990年至指定年的前一年共有多少天*/
}
yearday+=days(today); /*加上指定年中到指定日期的天數*/
day=yearday%5; /*求餘數*/
if(day>0&&day<4)
printf("he was fishing at that day.\n"); /*列印結果*/
else
printf("He was sleeping at that day.\n");
}
【12.抓交通肇事犯】
一輛卡車違反交通規則,撞人後逃跑。現場有三人目擊事件,但都沒有記住車號,只記下車號的一些特徵。甲說:牌照的前兩位數字是相同的;乙說:牌照的後兩位數字是相同的,但與前兩位不同;丙是數學家,他說:四位的車號剛好是一個整數的平方。請根據以上線索求出車號。
#include<stdio.h>
void main(){
int i,j,k;
int num;
for(i=0;i<=9;i++){ //車號前兩位的取值
for(j=0;j<=9;j++){ //車號後兩位的取值
if(i!=j){ //前兩位和後兩位不同
num=i*1000+i*100+j*10+j;
for(k=1;k*k<num;k++);
if(k*k==num)
printf("Lorry--No. is %d \n",num);
}
}
}
}
【13.該存多少錢】
假設銀行一年整存零取的月息為0.63%。現在某人手中有一筆錢,他打算在今後的五年中的年底取出1000元,到第五年時剛好取完,請算出他存錢時應存入多少。
#include<stdio.h>
void main(){
int i;
float total=0;
for(i=0;i<5;i++)
total=(total+1000)/(1+0.0063*12);
printf("He must save %.2f at first.\n",total);
}
【14.怎樣存錢利最大】
假設銀行整存整取存款不同期限的月息利率分別為:
0.63% 期限=1年
0.66% 期限=2年
0.69% 期限=3年
0.75% 期限=5年
0.84% 期限=8年
利息=本金*月息利率*12*存款年限。
現在某人手中有2000元錢,請通過計算選擇一種存錢方案,使得錢存入銀行20年後得到的利息最多(假定銀行對超過存款期限的那一部分時間不付利息)。
#include<stdio.h>
#include<math.h>
void main(){
int i8,i5,i3,i2,i1,n8,n5,n3,n2,n1;
float max=0,term;
for(i8=0;i8<3;i8++) /*窮舉所有可能的存款方式*/
for(i5=0;i5<=(20-8*i8)/5;i5++)
for(i3=0;i3<=(20-8*i8-5*i5)/3;i3++)
for(i2=0;i2<=(20-8*i8-5*i5-3*i3)/2;i2++){
i1=20-8*i8-5*i5-3*i3-2*i2;
term=2000.0*pow((double)(1+0.0063*12),
(double)i1)*pow((double)(1+2*0.0063*12),
(double)i2)*pow((double)(1+3*0.0069*12),
(double)i3)*pow((double)(1+5*0.0075*12),
(double)i5)*pow((double)(1+8*0.0084*12),
(double)i8);
/*計算到期時的本利合計*/
if(term>max){
max=term;
n1=i1;
n2=i2;
n3=i3;
n5=i5;
n8=i8;
}
}
printf("For max profit,he should save his money in a bank:\n");
printf(" made fixed deposit for 8 year: %d times\n",n8);
printf(" made fixed deposit for 5 year: %d times\n",n5);
printf(" made fixed deposit for 3 year: %d times\n",n3);
printf(" made fixed deposit for 2 year: %d times\n",n2);
printf(" made fixed deposit for 1 year: %d times\n",n1);
printf(" Toal: %.2f\n",max);
}
【15.捕魚和分魚】
A、B、C、D、E五個人在某天夜裡合夥去捕魚,到第二天凌晨時都疲憊不堪,於是各自找地方睡覺。日上三杆,A第一個醒來,他將魚分為五份,把多餘的一條魚扔掉,拿走自己的一份。B第二個醒來,也將魚分為五份,把多餘的一條魚扔掉,保持走自己的一份。C、D、E依次醒來,也按同樣的方法拿 走魚。問他們合夥至少捕了多少條魚?
#include<stdio.h>
void main(){
int n,i,x,flag=1;
for(n=6;flag;n++){
for(x=n,i=1&&flag;i<=5;i++)
if((x-1)%5==0) x=4*(x-1)/5;
else flag=0;
if(flag) break;
else flag=1;
}
printf("Total number of fish catched=%d\n",n);
}
【16.出售金魚】
買賣提將養的一缸金魚分五次出售,系統上一次賣出全部的一半加二分之一條;第二次賣出餘下的三分之一加三分之一條;第三次賣出餘下的四分之一加四分之一條;第四次賣出餘下的五分之一加五分之一條;最後賣出餘下的11條。問原來的魚缸中共有幾條金魚?
#include<stdio.h>
void main(){
int i,j,n=0,x;
for(i=23;n==0;i+=2) {
for(j=1,x=i;j<=4&&x>=11;j++)
if((x+1)%(j+1)==0)
x-=(x+1)/(j+1);
else {
x=0;
break;
}
if(j==5&&x==11) {
printf("There are %d fishes at first.\n",i);
n=1;
}
}
}
【17.平分七筐魚】
甲、乙、丙三位魚夫出海打魚,他們隨船帶了21只籮筐。當晚返航時,他們發現有七筐裝滿了魚,還有七筐裝了半筐魚,另外七筐則是空的,由於他們沒有秤,只好通過目測認為七個滿筐魚的重量是相等的,7個半筐魚的重量是相等的。在不將魚倒出來的前提下,怎樣將魚和筐平分為三份?
#include<stdio.h>
int a[3][3],count;
void main(){
int i,j,k,m,n,flag;
printf("It exists possible distribtion plans:\n");
for(i=0;i<=3;i++) {
a[0][0]=i;
for(j=i;j<=7-i&&j<=3;j++) {
a[1][0]=j;
if((a[2][0]=7-j-a[0][0])>3) continue;
if(a[2][0]<a[1][0]) break;
for(k=1;k<=5;k+=2) {
a[0][1]=k;
for(m=1;m<7-k;m+=2) {
a[1][1]=m;
a[2][1]=7-k-m;
for(flag=1,n=0;flag&&n<3;n++)
if(a[n][0]+a[n][1]<7&&a[n][0]*2+a[n][1]==7)
a[n][2]=7-a[n][0]-a[n][1];
else
flag=0;
if(flag){
printf("No.%d Full basket Semi--basket Empty\n",++count);
for(n=0;n<3;n++)
printf("fisher %c: %d %d %d\n", 'A'+n,a[n][0],a[n][1],a[n][2]);
}
}
}
}
}
}
【18.有限5位數】
個位數為6且能被3整除的五位數共有多少?
#include<stdio.h>
void main(){
long int i;
int count=0;
for(i=1000;i<9999;i++)
if(!((i*10+6)%3))
count++;
printf("count=%d\n",count);
}
【19. 8 除不盡的數】
一個自然數被8除餘1,所得的商被8除也餘1,再將第二次的商被8除後餘7,最後得到一個商為a。
又知這個自然數被17除餘4,所得的商被17除餘15,最後得到一個商是a的2倍。求這個自然數。
#include<stdio.h>
void main(){
int i;
for(i=0;;i++)
if(((i*8+7)*8+1)*8+1==(34*i+15)*17+4) {
printf("The required number is: %d\n",(34*i+15)*17+4);
break;
}
}
【20.一個奇異的三位數】
一個自然數的七進製表達式是一個三位數,而這個自然數的九進製表示也是一個三位數,且這兩個三位數的數碼正好相反,求這個三位數。
[題目分析與演算法設計]根據題意可知,七進位制和九進製表示的這全自然數的每一位一定小於7,可設其七進位制數形式為kji(i、j、k的取值分別為1~6),然後設其九進製表示形式為ijk。
#include<stdio.h>
void main(){
int i,j,k;
for(i=1;i<7;i++)
for(j=0;j<7;j++)
for(k=1;k<7;k++)
if(i*9*9+j*9+k==i+j*7+k*7*7){
printf("The special number with 3 digits is: ");
printf("%d%d%d(7)=%d%d%d(9)=%d(10)\n",k,j,i,i,j,k,i*9*9+j*9+k);
}
}
【21.4位反序數】
設N是一個四位數,它的9倍恰好是其反序數,求N。反序數就是將整數的數字倒過來形成的整數。例如:1234的反序數是4321。
#include<stdio.h>
void main(){
int i;
for(i=1002;i<1111;i++)
if(i%10*1000+i/10%10*100+i/100%10*10+i/1000==i*9)
printf("The number satisfied stats condition is: %d\n",i);
}
【22.求車速】
一輛以固定速度行駛的汽車,司機在上午10點看到里程錶上的讀數是一個對稱數(即這個數從左向右讀和從右向左讀是完全一樣的),為95859。兩小時後里程錶上出現了一個新的對稱數。問該車的速度是多少?新的對稱數是多少?
[演算法分析與設計]設所求對稱數為i,其初值為95589,對其依次遞增取值,將i值的每一位分解後與其對稱位置上的數進行比較,若每個對稱位置上的數皆相等,則可判定i即為所求的對稱數。
#include<stdio.h>
void main(){
int t,a[5];
long int k,i;
for(i=95860;;i++) {
for(t=0,k=100000;k>=10;t++) {
a[t]=(i%k)/(k/10);
k/=10;
}
if((a[0]==a[4])&&(a[1]==a[3])){
printf("The new symmetrical number kelometers is: %d%d%d%d%d\n", a[0],a[1],a[2],a[3],a[4]);
printf("The velocity of the car is: %.2f\n",(i-95859)/2.0);
break;
}
}
}
【23.阿姆斯特朗數】
如果一個正整數等於其各個數字的立方和,則稱該數為阿姆斯特朗數(亦稱為自戀性數)。
如 407=4^3+0^3+7^3就是一個阿姆斯特朗數。試程式設計求1000以內的所有阿姆斯特朗數。
#include<stdio.h>
void main(){
int i,t,k,a[3];
printf("There are follwing Armstrong number smaller than 1000:\n");
for(i=2;i<1000;i++) {
for(t=0,k=1000;k>=10;t++) {
a[t]=(i%k)/(k/10);
k/=10;
}
if(a[0]*a[0]*a[0]+a[1]*a[1]*a[1]+a[2]*a[2]*a[2]==i)
printf("%5d",i);
}
printf("\n");
}
【24.完全數】
如果一個數恰好等於它的因子之和,則稱該數為“完全數”。
#include<stdio.h>
void main(){
int a,i,m;
printf("There are following perfect numbers smaller than 1000: \n");
for(a=1;a<1000;a++) {
for(m=0,i=1;i<=a/2;i++)
if(!(a%i))
m+=i;
if(m==a)
printf("%4d",a);
}
printf("\n");
}
【26.親密數】
如果整數A的全部因子(包括1,不包括A本身)之和等於B;且整數B的全部因子(包括1,不包括B本身)之和等於A,則將整數A和B稱為親密數。求3000以內的全部親密數。
#include<stdio.h>
void main(){
int a,i,b,n;
printf("There are following friendly--numbers pair smaller than 3000:\n");
for(a=1;a<3000;a++) {
for(b=0,i=1;i<=a/2;i++)
if(!(a%i))
b+=i;
for(n=0,i=1;i<=b/2;i++)
if(!(b%i))
n+=i;
if(n==a&&a<b)
printf("%4d..%4d ",a,b);
}
printf("\n");
}
【27.自守數】
自守數是指一個數的平方的尾數等於該數自身的自然數。請求出200000以內的自守數
#include<stdio.h>
void main(){
long mul,number,k,ll,kk;
printf("It exists following automorphic nmbers small than 200000:\n");
for(number=0;number<200000;number++)
{
for(mul=number,k=1;(mul/=10)>0;k*=10);
kk=k*10;
mul=0;
ll=10;
while(k>0) {
mul=(mul+(number%(k*10))*(number%ll-number%(ll/10)))%kk;
k/=10;
ll*=10;
}
if(number==mul)
printf("%ld ",number);
}
printf("\n");
}
【28.迴文數】
列印所有不超過n (取n<256) 的其平方具有對稱性質的數(也稱迴文數)。
#include<stdio.h>
void main(){
int m[16],n,i,t,count=0;
long unsigned a,k;
printf("No. number it's square(palindrome)\n");
for(n=1;n<256;n++) {
k=0;t=1;a=n*n;
for(i=1;a!=0;i++){
m[i] = a%10;
a/=10;
}
for(;i>1;i--){
k+=m[i-1]*t;
t*=10;
}
if(k==n*n)
printf("%2d%10d%10d\n",++count,n,n*n);
}
}
【29.求具有abcd=(ab+cd)^2性質的四位數】
3025這個數具有一種獨特的性質:將它平分為二段,即30和25,使之相加後求平方,
即(30+25)2,恰好等於3025本身。請求出具有這樣性質的全部四位數。
#include<stdio.h>
void main(){
int n,a,b;
printf("There are following number with 4 digits satisfied condition\n");
for(n=1000;n<10000;n++) {
a=n/100;
b=n%100;
if((a+b)*(a+b)==n)
printf(" %d ",n);
}
printf("\n");
}
【30.求素數】
求素數表中1~1000之間的所有素數
#include<stdio.h>
void main(){
int n1,nm,i,j,flag,count=0;
do{
printf("Input START and END=?");
scanf("%d%d",&n1,&nm);
}while(!(n1>0&&n1<nm));
printf("...........PRIME TABLE(%d--%d)............\n",n1,nm);
if(n1==1||n1==2){
printf("%4d",2);
n1=3;
count++;
}
for(i=n1;i<=nm;i++) {
if(!(i%2))
continue;
for(flag=1,j=3;flag&&j<i/2;j+=2)
if(!(i%j))
flag=0;
if(flag)
printf(++count%15?"%4d":"%4d\n",i);
}
printf("\n");
}
【31.歌德巴赫猜想】
驗證:2000以內的正偶數都能夠分解為兩個素數之和(即驗證歌德巴赫猜想對2000以內的正偶數成立。
#include<stdio.h>
#include<math.h>
int fflag(int i) {
int j;
if(i<=1) return 0;
if(i==2) return 1;
if(!(i%2)) return 0;
for(j=3;j<=(int)(sqrt((double)i)+1);j+=2)
if(!(i%j)) return 0;
return 1;
}
void main(){
int i,n;
for(i=4;i<=2000;i+=2){
for(n=2;n<i;n++)
if(fflag(n))
if(fflag(i-n)) {
printf("%14d=%d+%d\n",i,n,i-n);
break;
}
if(n==i)
printf("error %d\n",i);
}
}
【32.要發就發】
“1898--要發就發”。請將不超過1993的所有素數從小到大排成第一行,第二行上的每個素數都等於它右肩上的素數之差。程式設計求出:第二行數中是否存在這樣的若干個連續的整數,它們的和恰好是1898?假好存在的話,又有幾種這樣的情況?
第一行:2 3 5 7 11 13 17......1979 1987 1993
第二行:1 2 2 4 2 4...... 8 6
#include<stdio.h>
#include<math.h>
#define NUM 320
int number[NUM]; //存放不超過1993的全部素數
int fun(int i){
int j;
if(i<=1) return 0; //判斷是否為素數,為1是素數,為0不是素數
if(i==2) return 1;
if(!(i%2)) return 0;
for(j=3;j<=(int)(sqrt((double)i)+1);j+=2)
if(!(i%j)) return 0;
return 1;
}
void main(){
int i,j,count=0;
printf("There are following primes sequesces in first row: \n"); //列出第一行中差值為1989的所有素數組合
for(j=0,i=3;i<=1993;i+=2){ //求出不超過1993的全部素數
if(fun(i))
number[j++]=i;
}
for(j--;number[j]>1898;j--){ //從最大的素數開始向1898搜尋
for(i=0;number[j]-number[i]>1898;i++); //迴圈查詢滿足條件的素數
if(number[j]-number[i]==1898) //若兩個素數的差為1898,則輸出
printf("(%d).%3d,.....,%d\n",++count,number[i],number[j]);
}
}
/*
There are follwing primes sequences in first row:
(1).89,......,1987
(2).53,......,1951
(3). 3,......,1901
*/
【35.素數幻方】
求四階的素數幻方。即在一個4X4 的矩陣中,每一個格填 入一個數字,使每一行、每一列和兩條對角線上的4 個數字所組成的四位數,均為可逆素數。
#include<stdio.h>
#include<math.h>
int number[210][5];
int select[110];
int array[4][5];
int count;
int selecount;
int larray[2][200];
int lcount[2];
int num(int number);
int ok(int number);
void process(int i);
void copy_num(int i);
int comp_num(int n);
int find1(int i);
int find2(void);
int find0(int num);
void p_array(void);
void main(){
int i,k,flag,cc=0,i1,i4;
printf("there are magic squares with invertable primes as follw:\n");
for(i=1001;i<9999;i+=2){ //求滿足條件的可逆素數
k=i/1000;
if(k%2!=0&&k!=5&&num(i)){ //若可逆素數的第一位不是偶數或5
number[count][0]=i; //存入陣列
process(count++); //分解素數的各位數字
if(number[count-1][2]%2!=0&& //若可逆素數滿足放在矩陣第一行
number[count-1][3]%2!=0&& //和最後一行的條件,記錄可逆素數的
number[count-1][2]!=5&& //下標,計數器加1
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[0][i]/100)
larray[0][lcount[0]++]=number[0][i]/100;
if(larray[1][lcount[1]-1]!=number[0][i]/10)
larray[1][lcount[1]++]=number[0][i]/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();
}
}
}
}
}
}
int 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;
}
int ok(nt 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;
}
void process(int i){ //將第i個整數分解為數字並存入陣列
int j,num;
num=number[i][0];
for(j=4;j>=1;j--,num/=10)
number[i][j]=num%10;
}
void copy_num(int i){ //將array[i][0]指向的素數的各位數字複製到array[i]中
int j;
for(j=1;j<=4;j++)
array[i][j]=number[array[i][0>[j];
}
int comp_num(int n){ //判斷array中每列的前n位是否與可逆素數允許的前n位矛盾
static int ii;