目录
1.素数对猜想
题目详情:
让我们定义dn为:dn=pn+1−pn,其中pi是第i个素数。显然有d1=1,且对于n>1有dn是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。
现给定任意正整数
N
(<105),请计算不超过N
的满足猜想的素数对的个数。
输入格式:
输入在一行给出正整数
N
。
输出格式:
在一行中输出不超过
N
的满足猜想的素数对的个数。
输入样例:
20
输出样例:
4
代码长度限制 16 KB
时间限制 400 ms
内存限制 64 MB
代码及解析如下:
#include <stdio.h>
#define P 100000
int isprime(int ); //判断一个数是否为素数
int a[P]; //存放N以内的素数
int main(){
int count=0; //计数器,计算素数对的个数
int i=0,j=0;
int N=0;
scanf("%d",&N);
for(i=0;i<=N;i++){
if(isprime(i)){ //
a[j++]=i; //将N以内的素数放到数组里
}
}
for(i=0;i<j;i++){
if((a[i+1]-a[i])==2){ //如果满足素数对的条件
count++; //则计数器加一
}
}
printf("%d",count);
}
int isprime(int x){
if(x<=1)return 0;
for(int i=2;i*i<=x;i++){
if(x%i==0){
return 0;
}
}
return 1;
}
2.数组元素循环右移问题
题目详情:
一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥0)个位置,即将A中的数据由(A0A1⋯AN−1)变换为(AN−M⋯AN−1A0A1⋯AN−M−1)(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?
输入格式:
每个输入包含一个测试用例,第1行输入N(1≤N≤100)和M(≥0);第2行输入N个整数,之间用空格分隔。
输出格式:
在一行中输出循环右移M位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。
输入样例:
6 2
1 2 3 4 5 6
输出样例:
5 6 1 2 3 4
代码及解析如下:
#include <stdio.h>
#define P 100
int main(){
int N=0,M=0; //N数组元素个数,M循环右移次数
scanf("%d %d",&N,&M);
int a[P];
int i=0;
for(i=0;i<N;i++){
scanf("%d",&a[i]); //输入数组元素
}
for(i=0;i<M;i++){ //循环右移M次
//先将最后一位数临时拷贝以下,防止被覆盖
int temp=a[N-1];
int j;
//再将每个数赋给它的后面一位,形成数组的一次右移
//该操作要从后往前执行
for(j=N-2;j>=0;j--){
a[j+1]=a[j];
}
//上面的循环结束后,j=-1,+1后把临时拷贝的a[n-1]赋进去,完成该次循环右移
a[j+1]=temp;
}
for(i=0;i<N;i++){
printf("%d",a[i]);
if(i<N-1)printf(" ");
}
return 0;
}
3.水仙花数
题目详情:
水仙花数是指一个N位正整数(N≥3),它的每个位上的数字的N次幂之和等于它本身。例如:153=13+53+33。 本题要求编写程序,计算所有N位水仙花数。
输入格式:
输入在一行中给出一个正整数N(3≤N≤7)。
输出格式:
按递增顺序输出所有N位水仙花数,每个数字占一行。
输入样例:
3
输出样例:
153
370
371
407
代码及解析如下:
#include <stdio.h>
int p(int ,int ); //定义函数计算N次幂
int main(){
int N; //输入N位数
scanf("%d",&N);
int mask=1;
//定义mask变量,可以算出N位数的起始区间
for(int i=0;i<N-1;i++){
mask*=10;
}
int sum;
//计算出N位数的起始区间,比如3位数的起始区间为100-999
for(int j=mask;j<mask*10;j++){
int m=j; //某一个N位数
sum=0;
while(m){
int temp=m%10; //将每个位上的数字取出来
sum+=p(temp,N); //计算每个位上的N次幂之和
m/=10;
}
if(j==sum)printf("%d\n",j);
}
return 0;
}
int p(int x,int y){ //计算N次幂
int i=1,j=1;
for(i=0;i<y;i++){
j*=x;
}
return j;
}
4.找出不是两个数组共有的元素
题目详情:
给定两个整型数组,本题要求找出不是两者共有的元素。
输入格式:
输入分别在两行中给出两个整型数组,每行先给出正整数N(≤20),随后是N个整数,其间以空格分隔。
输出格式:
在一行中按照数字给出的顺序输出不是两数组共有的元素,数字间以空格分隔,但行末不得有多余的空格。题目保证至少存在一个这样的数字。同一数字不重复输出。
输入样例:
10 3 -5 2 8 0 3 5 -15 9 100
11 6 4 8 2 6 -5 9 0 100 8 1
输出样例:
3 5 -15 6 4 1
代码及解析如下:
#include <stdio.h>
#define P 100
int main(){
int a[P],b[P];
int N,M,i,j;
scanf("%d",&N);
for(i=0;i<N;i++){
scanf("%d",&a[i]); //输入长度为N的数组a
}
scanf("%d",&M);
for(i=0;i<M;i++){
scanf("%d",&b[i]); //输入长度为M的数组b
}
int count=0;
int c[P]; //定义一个新数组存放两数组中相同的数
for(i=0;i<N;i++){ //先拿着数组a中的每个元素去比较数组b中的每个元素
for(j=0;j<M;j++){
if(a[i]==b[j]) //如果有相同的数,跳出该层循环
break;
}
if(j==M)c[count++]=a[i]; //j=M表示遍历整个数组b都没有相同的数
}
for(i=0;i<M;i++){
for(j=0;j<N;j++){
if(b[i]==a[j])break;
}if(j==N)c[count++]=b[i]; //拿着数组b中的每个数去比较数组a中的数,类似上述步骤
}
printf("%d",c[0]);
for(i=1;i<count;i++){
for(j=0;j<i;j++){
if(c[i]==c[j])break; //判断数组c中有无重复的数
}
if(j==i)printf(" %d",c[i]);
}
return 0;
}
5.找鞍点
题目详情:
一个矩阵元素的“鞍点”是指该位置上的元素值在该行上最大、在该列上最小。
本题要求编写程序,求一个给定的n阶方阵的鞍点。
输入格式:
输入第一行给出一个正整数n(1≤n≤6)。随后n行,每行给出n个整数,其间以空格分隔。
输出格式:
输出在一行中按照“行下标 列下标”(下标从0开始)的格式输出鞍点的位置。如果鞍点不存在,则输出“NONE”。题目保证给出的矩阵至多存在一个鞍点。
输入样例:
4
1 7 4 1
4 8 3 6
1 6 1 2
0 7 8 9
输出样例 :
2 1
代码及解析如下:
#include <stdio.h>
#define P 100
int main(){
int a[P][P];
int n;
scanf("%d",&n);
int i,j;
for(i=0;i<n;i++){
for(j=0;j<n;j++){
scanf("%d",&a[i][j]); //输入n*n的矩阵
}
}
int b=0,k;
int temp=0;
for(i=0;i<n;i++){
for(j=0;j<n;j++){
if(a[i][j]>=a[i][b]){ //先找到每行上最大的数a[i][b]
b=j;
}
}
temp=1;
for(k=0;k<n;k++){
if(a[k][b]<a[i][b]){ //在该数所在的列上逐行向下找有没有小于a[i][b]的数
temp=0; //如果有,则标记0,说明a[i][b]不是要找的数
break;
}
}
if(temp)break; //如果没有,说明数a[i][b]在所在列上是最小的
}
if(temp)printf("%d %d",i,b); //打印其所在位置i,b
else printf("NONE");
return 0;
}
6.验证“哥德巴赫猜想”
题目详情:
数学领域著名的“哥德巴赫猜想”的大致意思是:任何一个大于2的偶数总能表示为两个素数之和。比如:24=5+19,其中5和19都是素数。本实验的任务是设计一个程序,验证20亿以内的偶数都可以分解成两个素数之和。
输入格式:
输入在一行中给出一个(2, 2 000 000 000]范围内的偶数N。
输出格式:
在一行中按照格式“N = p + q”输出N的素数分解,其中p ≤ q均为素数。又因为这样的分解不唯一(例如24还可以分解为7+17),要求必须输出所有解中p最小的解。
输入样例:
24
输出样例:
24 = 5 + 19
代码及解析如下:
#include <stdio.h>
int p(int );
int main(){
long long n; //题目说20亿以内,所以整数要定义的足够大
scanf("%d",&n);
int i;
for(i=2;i<n;i++){
if(p(i)&&p(n-i)){ //满足:1.两数相加为n 2.两数都是素数
printf("%d = %d + %d",n,i,n-i);
break;
}
}
return 0;
}
int p(int x){ //判断是否为素数
if(x<=1)return 0;
for(int i=2;i*i<=x;i++){
if(x%i==0)
return 0;
}
return 1;
}
补:long/int型的范围 -2147483648()~~~2147483647(
)
long long型的范围-9223372036854775808()~~~9223372036854775807(
)
7.黑洞数
题目详情:
黑洞数也称为陷阱数,又称“Kaprekar问题”,是一类具有奇特转换特性的数。
任何一个各位数字不全相同的三位数,经有限次“重排求差”操作,总会得到495。最后所得的495即为三位黑洞数。所谓“重排求差”操作即组成该数的数字重排后的最大数减去重排后的最小数。(6174为四位黑洞数。)
例如,对三位数207:
- 第1次重排求差得:720 - 27 = 693;
- 第2次重排求差得:963 - 369 = 594;
- 第3次重排求差得:954 - 459 = 495;
以后会停留在495这一黑洞数。如果三位数的3个数字全相同,一次转换后即为0。
任意输入一个三位数,编程给出重排求差的过程。
输入格式:
输入在一行中给出一个三位数。
输出格式:
按照以下格式输出重排求差的过程:
序号: 数字重排后的最大数 - 重排后的最小数 = 差值
输入样例:
123
输出格式:
1: 321 - 123 = 198
2: 981 - 189 = 792
3: 972 - 279 = 693
4: 963 - 369 = 594
5: 954 - 459 = 495
代码及解析如下:
#include <stdio.h>
int p(int );
int q(int );
int main(){
int n,p=1;
scanf("%d",&n); //输入某一个三位数数
int n1,n2;
while(1){
int i,j,k,t;
i=n%10;
j=n/10%10;
k=n/100; //把该三位数的各位数分别取出来
if(i<j){
t=i;
i=j;
j=t;
} //
if(i<k){ // 比较各位数上的大小
t=i; //
i=k;
k=t;
}
if(j<k){
t=j;
j=k;
k=t;
}
n1=100*k+10*j+i; //重排后最小的数
n2=100*i+10*j+k; //重排后最大的数
n=n2-n1;
printf("%d: %d - %d = %d\n",p,n2,n1,n);
p++;
if(n==495)break; //判断两数相减是不是黑洞数
}
return 0;
}
8.装箱问题
题目详情:
假设有N项物品,大小分别为s1、s2、…、si、…、sN,其中si为满足1≤si≤100的整数。要把这些物品装入到容量为100的一批箱子(序号1-N)中。装箱方法是:对每项物品, 顺序扫描箱子,把该物品放入足以能够容下它的第一个箱子中。请写一个程序模拟这种装箱过程,并输出每个物品所在的箱子序号,以及放置全部物品所需的箱子数目。
输入格式:
输入第一行给出物品个数N(≤1000);第二行给出N个正整数si(1≤si≤100,表示第i项物品的大小)。
输出格式:
按照输入顺序输出每个物品的大小及其所在的箱子序号,每个物品占1行,最后一行输出所需的箱子数目。
输入样例:
8
60 70 80 90 30 40 10 20
输出样例:
60 1
70 2
80 3
90 4
30 1
40 5
10 1
20 2
5
代码及解析如下:
#include <stdio.h>
#define P 1001
int main(){
int n;
scanf("%d",&n); //输入物品个数
int a[P],b[P]; //数组a用力存放物品的大小,数组b用来表示每个箱子存了多大的东西
int i,j;
for(i=0;i<n;i++){
scanf("%d ",&a[i]); //输入每个物品的大小
b[i]=0; //刚开始箱子什么都每存,初始化位0
}
int max=0;
for(i=0;i<n;i++){ //每一个物品,都从1号箱子开始遍历
for(j=1;j<=n;j++){ //
if(a[i]+b[j]<=100){ //判断该物品能否放入当前的箱子
b[j]+=a[i]; //
printf("%d %d\n",a[i],j);
if(max<j){
max=j; //计算用了多少箱子
}
break;
}
}
}
printf("%d",max);
return 0;
}
9.IP地址转换
题目详情:
一个IP地址是用四个字节(每个字节8个位)的二进制码组成。请将32位二进制码表示的IP地址转换为十进制格式表示的IP地址输出。
输入格式:
输入在一行中给出32位二进制字符串。
输出格式:
在一行中输出十进制格式的IP地址,其由4个十进制数组成(分别对应4个8位的二进制数),中间用“.”分隔开。
输入样例:
11001100100101000001010101110010
输出样例:
204.148.21.114
代码及解析如下:
//题目中说是32位IP地址,远远超出整形变量的取值范围
//所以不能定义整型变量来做,应考虑数组
#include <stdio.h>
int f(char *);
int main(){
char a[4][8]; //IP地址分为四节,每节8个二进制数,所以定义一个4*8的二维数组
for(int i=0;i<4;i++){
scanf("%s",a[i]); //输入二维数组
}
int n1=f(a[0]);
int n2=f(a[1]);
int n3=f(a[2]);
int n4=f(a[3]);
printf("%d.%d.%d.%d",n1,n2,n3,n4);
return 0;
}
int f(char *b){ //二进制转十进制
int sum=0;
int n=128; //2的7次方
for(int i=0;i<8;i++){
sum+=(b[i]-'0')*n; //b[i]是字符型,减‘0’为当前的整形二进制
n/=2; //将该位上的二进制数从高到低乘上该位的位权
} //得到的就是十进制数
return sum;
}
10.龟兔赛跑
题目详情:
乌龟与兔子进行赛跑,跑场是一个矩型跑道,跑道边可以随地进行休息。乌龟每分钟可以前进3米,兔子每分钟前进9米;兔子嫌乌龟跑得慢,觉得肯定能跑赢乌龟,于是,每跑10分钟回头看一下乌龟,若发现自己超过乌龟,就在路边休息,每次休息30分钟,否则继续跑10分钟;而乌龟非常努力,一直跑,不休息。假定乌龟与兔子在同一起点同一时刻开始起跑,请问T分钟后乌龟和兔子谁跑得快?
输入格式:
输入在一行中给出比赛时间T(分钟)。
输出格式:
在一行中输出比赛的结果:乌龟赢输出
@_@
,兔子赢输出^_^
,平局则输出-_-
;后跟1空格,再输出胜利者跑完的距离。
输入样例:
242
输出样例:
@_@ 726
代码及解析如下:
#include <stdio.h>
int main(){
int t,n=0,m=0; //n乌龟前进米数,m兔子前进米数
scanf("%d",&t);
int i;
int count=0; //计算兔子休息的时间
for(i=0;i<t;i++){
n+=3; //乌龟每分钟跑3米
if(i%10==0&&m>n&&count<30){ //如果兔子跑了10分钟且超过乌龟且兔子不处于休息状态
count++; //兔子开始休息
}
else if(count==0||count==30){ //如果兔子一直在跑或兔子刚休息结束
m+=9;
count=0; //休息时间从0开始计数
}
else count++; //兔子处于休息状态
}
if(n>m){
printf("@_@ %d",n);
}
else if(m>n){
printf("^_^ %d",m);
}
else{
printf("-_- %d",m);
}
return 0;
}
注: 本栏目所有的题目均来自于学校程序设计课程的平时作业,如果对您有帮助的话,请点赞加关注,有任何不理解的地方也可以在评论区中留言或者私信我哦!