题目:
1 有这样一个数字,ABCD * E ==DCBA ,其中各个数字不相等,编写一个程序,计算出ABCD各代表什么数字。
#include <stdio.h>
int fun(int i,int j);
int reverse(int i);
int main()
{
int i,j;
for (i=1000; i<9999; i++)
for(j=1; j<10; j++)
{
if(i*j==reverse(i)&&fun(i,j))
{
printf("%d\n",i);
printf("* %d\n",j);
printf("-------\n");
printf("%d\n\n",i*j);
}
}
return 0;
}
int reverse(int i)//求i的倒置数
{
int r=0;
while(i)
{
r=r*10+i%10;
i=i/10;
}
return r;
}
int fun(int i,int j)//判断是否有重复数字
{
int buf[4],k=0;
while(i)
{
buf[k]=i%10;
i=i/10;
k++;
}
if(buf[0]==buf[1])
return 0;
if(buf[0]==buf[2])return 0;
if(buf[0]==buf[3])return 0;
if(buf[0]==j)return 0;
if(buf[1]==buf[2])return 0;
if(buf[1]==buf[3])return 0;
if(buf[1]==j)return 0;
if(buf[2]==buf[3])return 0;
if(buf[2]==j)return 0;
if(buf[3]==j)return 0;
return 1;
}
2
3对新婚夫妇参加婚礼,3个新郎为A、B、C,3个新娘为X、Y、Z.有人不知道谁和谁结婚,于是询问了6位新人中的3位,但听到的回答是这样的:A说他将和X结婚:X说她的未婚夫是C:C说他将和Z结婚。这人听后知道他们在开玩笑,全是假话。请编程找出谁将和谁结婚
#include <stdio.h>
int match(int i,int j,int k,char wife[]);
int main()
{
char husband[3]= {'A','B','C'},wife[3]= {'X','Y','Z'};
int i,j,k;
for (i=0; i<3; i++)
for (j=0; j<3; j++)
for (k=0; k<3; k++)
if(i!=j&&i!=k&&j!=k)
{
if(match(i,j,k,wife))
{
printf("husband wife\n");
printf("A----%c\n",wife[i]);
printf("B----%c\n",wife[j]);
printf("C----%c\n",wife[k]);
}
}
return 0;
}
int match(int i,int j,int k,char wife[])
{
if(wife[i]=='X')return 0;
if(wife[k]=='X')return 0;
if(wife[k]=='Z')return 0;
return 1;
}
3 分解质因数
#include<stdio.h>
int isPrime(int a)//判断是否是质因数
{
int i;
for(i=2; i<=a-1; i++)
{
if(a%i==0)
return 0;
}
return 1;
}
void PrimeFactor(int n)//分解质因数,并递归调用
{
int i;
if(isPrime(n))
printf("%d",n);
else
{
for(i=2; i<=n-1; i++)
{
if(n%i==0)
printf("%d ",i);
if(isPrime(n/i))
{
printf("%d ",n/i);
break;
}
else
PrimeFactor(n/i);
break;
}
}
}
int main()
{
int n;
scanf("%d",&n);
PrimeFactor(n);
return 0;
}
4 魔幻方阵,在n*n的矩阵中,填写n^2个数字,使得它的每一行,每一列以及两个对角线的和均相等
解法:
#include <stdio.h>
int match(int i, int j, int k, int l, int m, int n, int o, int p, int q)
{
if(i!=j && i!=k && i!=l && i!=m && i!=n && i!=o && i!=p && i!=q && j!=k && j!=l && j!=m && j!=n && j!=o && j!=p && j!=q && k!=l && k!=m && k!=n && k!=o && k!=p && k!=q && l!=m && l!=n && l!=o && l!=p && l!=q && m!=n && m!=o && m!=p && m!=q && n!=o && n!=p && n!=q && o!=p && o!=q && p!=q)
return 1;
else
return 0;
}
int justic(int i, int j, int k ,int l, int m, int n, int o, int p, int q)
{
if(i+j+k==l+m+n && i+j+k==o+p+q && i+l+o==j+m+p && i+l+o==k+n+q && i+m+q==k+m+o)
return 1;
else
return 0;
}
void getMatrix()
{
int i,j,k,l,m,n,o,p,q;
for(i=1;i<=9;i++)
for(j=1;j<=9;j++)
for(k=1;k<=9;k++)
for(l=1;l<=9;l++)
for(m=1;m<=9;m++)
for(n=1;n<=9;n++)
for(o=1;o<=9;o++)
for(p=1;p<=9;p++)
for(q=1;q<=9;q++)
{
if(match(i,j,k,l,m,n,o,p,q))
if(justic(i,j,k,l,m,n,o,p,q)){
printf("%d %d %d\n",i,j,k);
printf("%d %d %d\n",l,m,n);
printf("%d %d %d\n",o,p,q);
return;
}
}
}
int main(int argc, char *argv[])
{
getMatrix();
return 0;
}
另一个简单解法: 依次将1到N^2填入矩阵,填入的位置有如下规则确定。
*第一个元素放在第一行中间一列
*下一个元素存放在当前元素的上一行、下一列
*如上一行、下一列已经有内容,则下一个元素存放在当前列的下一行。
5 将1~8这8个数字随机的填写到3*3的外层圆圈中,只剩下中间一个空圆圈。规定每次只能移动到空圆圈中,要求将数阵中的数字有序
本质就是排序,而且是带有交换性质的排序方法。我用的是选择排序,还可用冒泡排序。
#include<stdio.h>
void Print(int m[]);
int getstep(int m[]);
int main()
{
int i , m[8];
for(i=0 ; i<8 ; i++)
scanf("%d",&m[i]);
Print(m);
printf("\n");
getstep(m);
Print(m);
return 0;
}
void Print(int m[])
{
printf("[%d]--[%d]--[%d]\n",m[0],m[1],m[2]);
printf("| %c | %c |\n" , 92 , 47);
printf("[%d]--[ --[%d]\n",m[7],m[3]);
printf("| %c | %c |\n" , 47 , 92);
printf("[%d]--[%d]--[%d]\n",m[6],m[5],m[4]);
}
int getstep(int m[])
{
int i , j , temp;
for (i =0 ; i<7 ; i++)
for(j=0; j<7-i; j++)
if(m[j]>m[j+1])
{
temp=m[j];
m[j]=m[j+1];
m[j+1]=temp;
}
}
(6)
3个嫌疑犯在法官面前各执一词,甲说:乙在说谎:乙说:丙在说谎;丙说:甲乙两人都在说谎。法官为了难,甲乙丙三人到底谁在说谎,谁说的是真话?
【题目分析】
这是一道十分有趣的逻辑推理问题。解决这类逻辑推理问题最简单直观的方法是使用穷举法。甲乙丙三人中任何人所说的话无外乎有两种可能,即真和假。如果用1表示真,用0表示假,甲乙丙三人所说的话的真假情况限定在以下范围内。
甲乙丙
000
001……
#include<stdio.h>
int main()
{
int a,b,c;
for (a=0; a<=1; a++)
for (b=0; b<=1; b++)
for (c=0; c<=1; c++)
if((a&&!b || !a&&b) && (b&&!c || !b&&c) && (c&&a+b==0 || !c&&a+b!=0))
{
printf(" 甲 told a %s\n",a?"truth":"lie");
printf(" 乙 told a %s\n",b?"truth":"lie");
printf(" 丙 told a %s\n",c?"truth":"lie");
}
return 0;
}
(7)验证四方定理
所有自然数最多只要4个数的平方和就可以表示,编写一个程序验证
#include<cstdio>
int mode_1(int n) //N=a^2
{
int i;
for(i=1;i<n;i++)
if(i*i==n)
{
printf("%d*%d=%d\n",i,i,n);
return 1;
}
return 0;
}
int mode_2(int n) //N=a^2 + b^2
{
int i,j;
for(i=1;i*i<n;i++)
for(j=i;j*j<n;j++)
if(i*i+j*j==n)
{
printf("%d^2+%d^2=%d\n",i,j,n);
return 1;
}
return 0;
}
int mode_3(int n) //N=a^2 + b^2 + c^2
{
int i,j,k;
for(i=1;i*i<n;i++)
for(j=i;j*j<n;j++)
for(k=j;k*k<n;k++)
if(i*i+j*j+k*k==n)
{
printf("%d^2+%d^2+%d^2=%d\n",i,j,k,n);
return 1;
}
return 0;
}
int mode_4(int n) //N=a^2 + b^2 + c^2 + d^2
{
int i,j,k,l;
for(i=1;i*i<n;i++)
for(j=i;j*j<n;j++)
for(k=j;k*k<n;k++)
for(l=k;l*l<n;l++)
if(i*i+j*j+k*k+l*l==n)
{
printf("%d^2+%d^2+%d^2+%d^2=%d\n",i,j,k,l,n);
return 1;
}
return 0;
}
void prove(int n)
{
if(mode_1(n))
printf("It has vertified Four Square theorem\n");
else if(mode_2(n))
printf("It has vertified Four Square theorem\n");
else if(mode_3(n))
printf("It has vertified Four Square theorem\n");
else if(mode_4(n))
printf("It has vertified Four Square theorem\n");
else
printf("ERROR!");
}
int main()
{
int n;
scanf("%d",&n);
prove(n);
return 0;
}
这个解法想起来简单,不过太长。以下是另一种解法,这个解法比较巧,我是想不到,受教了。
# include <stdio.h>
# include <math.h>
int f(int n, int a[], int idx)
{
int i;
if(n==0) return 1;
if(idx==4) return 0;
for( i=(int)sqrt(n); i>=1; i--)
{
a[idx] = i;
if(i * i == n || f(n - i * i, a, idx + 1)) return 1; //调用递归
}
return 0;
}
int main(int argc, char* argv[])
{
for(;;)
{
int number;
scanf("%d",&number);
int a[] = {0,0,0,0};
int r = f(number, a, 0);
printf("%d: %d %d %d %d\n", r, a[0], a[1], a[2], a[3]);
}
return 0;
}
(8)编写一个程序,要求从一个整数序列中找出最小的元素,并用递归的方法实现
# include <stdio.h>
#define N 100
int GetMin(int a[] , int n)
{
int v1, v2 , v3;
if(n==1)
return a[0];
if(n%2==0) //分情况讨论,判断整数的个数为奇数或偶数
{
v1=GetMin(a, n/2);
v2=GetMin(a+n/2 , n/2);
if(v1>v2)
return v2;
else
return v1;
}
if(n%2!=0)
{
v1=GetMin(a, n/2);
v2=GetMin(a+n/2+1 , n/2);
v3=a[n/2];
if(v1<v2)
{
if(v1<v3)
return v1;
else
return v3;
}
else
{
if(v2<v3)
return v2;
else
return v3;
}
}
}
int main()
{
int min;
int a[9]={1,3,6,8,9,4,7,6,4};
min=GetMin(a , 9);
printf("%d",min);
return 0;
}
(9)渔夫捕鱼问题
A、B、C、D、E这5个渔夫夜间合伙捕鱼,凌晨时都疲倦不堪,各自在河边的树丛中找地方睡着了。待日上三竿,渔夫A第一个醒来,他将鱼分作5份,把多余的一条扔回河中,拿自己的一份回家去了。渔夫B第二个醒来,也将鱼分作5份,扔掉多余的一条拿走自己的一份,接着C、D、E依次醒来,也都按同样的办法分鱼,问5个渔夫至少合伙捕了多少条鱼?试编程序算出
解决这个问题需要从最后一个渔夫入手,按照分鱼的原则,最后一次剩下的可能为6,11,16,21……加入为6,那D为8.5,显然是不合逻辑的。所以重新取E可能的值。
# include <stdio.h>
#define MAX 1000
int main()
{
int last_fish;
int s;
int flag;
int i , n;
for(n=1; n<MAX; n++)
{
last_fish=5*n+1;
s=last_fish;
flag=1;
for(i=0; i<4; i++)
{
if((5*s)%4==0)
s=(5*s)%4+1;
else
{
flag=0;
break;
}
}
if(flag==1)
{
printf("最少%d:条\n",s);
break;
}
}
return 0;
}
(10)在选美比赛的现场,有一批选手参加比赛,比赛的规则是最后得分越高,名次越低,
当比赛结東时,要在现场按照选手的出场顺序(即选手的序号)宣布最后得分和最后名
次,获得相同分数的选手具有相同的名次,名次连续编号,不用考虑同名次的选手人数,
例如:
选手序号为:
1,2,3,4,5,6,7
选手得分为
5,3,4,7,3,5,6
名次为
3,1,2,5,1,3,4
这个问题不能用排列解决,应结合结构体,组成结构体数组
# include <stdio.h>
typedef struct player
{
int num;
int score;
int rand;
} P;
void sortScore(P psn[],int n)
{
int i,j;
P temp;
for(i=0;i<n-1;i++)
for(j=0;j<n-1-i;j++)
{
if(psn[j].score>psn[j+1].score)
{
temp=psn[j];
psn[j]=psn[j+1];
psn[j+1]=temp;
}
}
}
void setRand(P psn[] , int n)
{
int i,j=2;
psn[0].rand=1;
for(i=1;i<n;i++)
{
if(psn[i].score !=psn[i-1].score)
{
psn[i].rand=j;
j++;
}
else
psn[i].rand=psn[i-1].rand;
}
}
void sortNum(P psn[], int n)
{
int i,j;
P tmp;
for(i=0;i<n-1;i++)
for(j=0;j<n-1-i;j++)
{
if(psn[j].num>psn[j+1].num)
{
tmp=psn[j];
psn[j]=psn[j+1];
psn[j+1]=tmp;
}
}
}
void sortRand(P psn[],int n)
{
sortScore(psn,n);//以分数为关键字排列
setRand(psn,n);//按照分数拍名次
sortNum(psn,n);//按照序号重新排列
}
int main()
{
P psn[7]= {{1,5,0},{2,3,0},{3,4,0},{4,7,0},{5,3,0},{6,5,0},{7,6,0}};
int i;
sortRand(psn , 7);
printf("num score rand \n");
for(i=0;i<7;i++)
{
printf("%d%6d%6d\n",psn[i].num, psn[i].score, psn[i].rand);
}
return 0;
}
(11)顺序表的就地逆置
利用原表的存储空间将顺序表逆置
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 10
typedef struct
{
int *base;
int length;
} sqlist;
void reverse(sqlist *l)//逆置
{
int low=0 , high=l->length-1;
int buf , i;
for(i=0;i<l->length/2 ; i++)
{
buf=l->base[low];
l->base[low] = l->base[high];
l->base[high]= buf;
low++;
high--;
}
}
int main()
{
int a,i=0;
sqlist l;
l.base=(int *)malloc(sizeof(int)*MAXSIZE);
l.length=0;
scanf("%d",&a);
while(i<=9&&a!= -1)
{
l.base[i]=a;
l.length++;
i++;
scanf("%d",&a);
}
reverse(&l);
for(i=0; i<l.length ; i++)
printf("%d " , l.base[i]);
return 0;
}