文章目录
前言:
相信经过基础篇的训练之后,大家已经对这类oj题目的已经熟悉了。
还有其他前言在基础篇1-29中
如果有问题交流咨询,可以加入QQ群:673852347
30 蟠桃记
问题描述 :
喜欢西游记的同学肯定都知道悟空偷吃蟠桃的故事,你们一定都觉得这猴子太闹腾了,其实你们是有所不知:悟空是在研究一个数学问题!什么问题?他研究的问题是蟠桃一共有多少个!不过,到最后,他还是没能解决这个难题,呵呵,当时的情况是这样的:第一天悟空吃掉桃子总数一半多一个,第二天又将剩下的桃子吃掉一半多一个,以后每天吃掉前一天剩下的一半多一个,到第n天准备吃的时候只剩下一个桃子。聪明的你,请帮悟空算一下,他第一天开始吃的时候桃子一共有多少个呢?
输入说明 :
输入数据有多组,每组占一行,包含一个正整数n(1<n<30),表示只剩下一个桃子的时候是在第n天发生的。
输出说明 :
对于每组输入数据,输出第一天开始吃的时候桃子的总数,每个测试实例占一行,行首与行尾无多余空格,行与行之间无空行。
输入范例 :
2
29
14
7
11
输出范例 :
4
805306366
24574
190
3070
AC代码:
可以以只剩一个桃子的这一天作为起始天数,然后可以推得前一天的,进而得到一开始第n天的。代码如下
#include<stdio.h>// summershell
int main()//水题,倒推
{
int n,a[31],i;
for(i=1,a[1]=1;i<=30;++i)a[i+1]=(a[i]+1)*2;
while(scanf("%d",&n)!=EOF)
printf("%d\n",a[n]);
return 0;
}
31 素数和
问题描述 :
求1~n之间所有素数的和
输入说明 :
第一行,输入N
以下N行,每行一个数字n(N<100,n<1000)
输出说明 :
N行,每行为1~n(包括n)之间素数的和
Solution:
素数打表,然后设置一个数组记录1-n之间的和 直接输出即可
#include<stdio.h>// summershell
int pri[1001],sum[1001];
void prime()
{
for(int i=0;i<1001;i++)pri[i]=1;
pri[0]=pri[1]=sum[0]=sum[1]=0;
for(int i=2,counter=2;i<1001;i++)
{
if(pri[i])
{
sum[counter]=sum[counter-1]+i;
for(int j=i+i;j<1001;j+=i)
pri[j]=0;
}
else sum[counter]=sum[counter-1];//1-n的素数和存进数组里面
counter++;
}
}
int main()//水题
{
int n,t;
prime();
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
printf("%d\n",sum[n]);
}
return 0;
}
32 完数个数
问题描述 :
完数的定义:如果一个大于1的正整数的所有真因子(不包括自己的那些因子)之和等于它的本身,则称这个数是完数,比如6,28都是完数:6=1+2+3;28=1+2+4+7+14。
本题的任务是判断两个正整数之间完数的个数。
输入说明 :
第一行是一个正整数n,表示测试实例的个数,然后就是n个测试实例,每个实例占一行,由两个正整数num1和num2组成,(1<num1,num2<10000)
输出说明 :
对于每组测试数据,请输出num1和num2之间(包括num1和num2)存在的完数个数。
#include<stdio.h>// :summershell
#include<math.h>
int sum[10001]={0,0};//sum存放0-n个完数的个数,然后作差即可
int wanshu(int a)
{
if(a==1)return 0;
int t=1,i;
for(i=2;i<sqrt(a);i++)if(a%i==0)t+=a/i+i;
if(i==sqrt(a))t+=i;
return t==a?1:0;
}
int main()//水题
{
int n,num1,num2,temp;
for(int i=2,counter=2;i<10001;i++)
{
if(wanshu(i))sum[counter]=sum[counter-1]+1;
else sum[counter]=sum[counter-1];
counter++;
}
scanf("%d",&n);
while(n--)
{
scanf("%d %d",&num1,&num2);
if(num1>num2){temp=num1;num1=num2;num2=temp;}
printf("%d\n",sum[num2]-sum[num1]+wanshu(num1));
}
return 0;
}
33 九九乘法表
问题描述 :
按如下形式输出九九乘法表:
输入说明 :
输入一个整数n(1<=n<=9),表示输出nn乘法表。
输出说明 :
输出三个nn乘法表,乘法表中每一个数字均占4格(不足4格的左边补空格)。每一行的最后一个数字之后无空格。每个乘法表后有一个空行(空行中无空格)。 第三个乘法表中,第二行的4和第一行的2对齐,第三行的9和第二行的6对齐,依次类推。
Caution:
控制格式!!!very important
#include<stdio.h>// summershell :QA+_+AQ:
int main()//数和数之间的空格用4d即可,不用再加空格了,不然会PE
{
int n,i,j;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)printf("%4d",i*j);
printf("\n");
}
printf("\n");
for(i=1;i<=n;i++)
{
for(j=1;j<=i;j++) printf("%4d",i*j);
printf("\n");
}
printf("\n");
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
if(i<=j)
printf("%4d",i*j);
else printf(" ");
printf("\n");
}
printf("\n");
return 0;
}
34 放大的X
问题描述 :
请你编程画一个放大的’X’。
如2*2的’X’应如下所示:
XX
XX
5*5的’X’如下所示:
X X
X X
X
X X
X X
输入说明 :
输入数据第一行是一个整数T,表示有T组测试数据;
接下来有T行,每行有一个正数n(2 <= n <= 80),表示放大的规格。
输出说明 :
对于每一个n打印一个规格为n * n放大的’X’;每组输出后面空一行。
注意:每一行输出的字符X为大写的’X’,第一行的最前与最后都无空格,每行的最后都无空格。
Caution:
找规律 一共5行 每行的X是在主副对角线上 控制输出
#include<stdio.h>// summershell :QA+_+AQ:
int main()//水题
{
int n,T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=(i<=n/2?n-i+1:i);j++)
{
if(j==i || j==n-i+1)printf("X");
else printf(" ");
}
printf("\n");
}
printf("\n");
}
return 0;
}
35 空心三角形
问题描述 :
把一个字符三角形掏空,就能节省材料成本,减轻重量,但关键是为了追求另一种视觉效果。在设计的过程中,需要给出各种花纹的材料和大小尺寸的三角形样板,通过电脑临时做出来,以便看看效果。
输入说明 :
第一行是一个数字T ( T < 30 ),接下来有T 行,表示有T 组测试数据 :
每行包含一个字符和一个整数n(0<n<41),不同的字符表示不同的花纹,整数n表示等腰三角形的高。显然其底边长为2n-1。
输出说明 :
每个样板三角形之后应空上一行。
样板三角形最下面一行没有空格,其余行的最后没有空格。
Catution:
n+i-1是每行的尾元素的位置 是34题的下半部分
#include<stdio.h>// summershell :QA+_+AQ:
int main()//水题,和34题如出一辙
{
int n,T;
char c,t;
scanf("%d",&T);
while(T--)
{
scanf("%c%c%d",&t,&c,&n);//吃掉换行符
for(int i=1;i<n;i++)
{
for(int j=1;j<=n+i-1;j++)
{
if(j==n-i+1 || j==n+i-1)printf("%c",c);
else printf(" ");
}
printf("\n");
}
for(int i=1;i<=2*n-1;i++)printf("%c",c);
printf("\n\n");
}
return 0;
}
36 水果价格
问题描述 :
一家水果店出售四种水果,每公斤价格的苹果(代码为a)1.5元,橘子(代码为o)1.4元,香蕉(代码为b)1.48元,菠萝(代码为p)1.08元。编一个程序,使售货员只要在键盘上打入货品的代码及重量,计算机将显示货品名、单价、重量及总价。
输入说明 :
你的程序需要从标准输入设备(通常为键盘)中读入多组测试数据。
每组测试数据的第一行为一个整数m,表示有m件货品要被购买。在接下来的m行中,每行输入两个值d,g。d表示货品的代码,g表示重量。两组数据之间没有多余的空行。
输出说明 :
对每组测试数据,你的程序需要向标准输出设备(通常为启动该程序的终端)依次输出一组对应的答案。对应每组输入,输出货品名、单个总价及全部总价。具体格式参照样例输出:第一行apple前为7个空格,之后为2个空格,其他水果名后都是1个空格,sum后没有空格;第二行price后有2个空格,其后关于价格的表示多为占7格2位小数且左对齐,但其中pineapple为占10格2位小数且左对齐,注意sum的价格仍然占7格,如第一组样例中的54.60后还有2个空格;第三行weight后有1个空格,其后的数据与第二行一致。每两组数据之间有一个空行,最后一组测试数据之后没有空行。
#include<stdio.h>// summershell
int main()//水题
{
double a[5],temp;
int n,counter=1;
char c,t;
while(scanf("%d",&n)!=EOF)
{
for(int i=0;i<5;i++)a[i]=0.0;
for(int i=0;i<n;i++)
{
scanf("%c%c %lf",&t,&c,&temp);
if(c=='a')a[0]+=temp;
if(c=='o')a[1]+=temp;
if(c=='b')a[2]+=temp;
if(c=='p')a[3]+=temp;
}
if(counter++!=1)printf("\n");
printf(" apple orange banana pineapple sum\n");
printf("price %-7.2f%-7.2f%-7.2f%-10.2f%-7.2f\n",a[0]*1.5,a[1]*1.4,a[2]*1.48,a[3]*1.08,a[0]*1.5+a[1]*1.4+a[2]*1.48+a[3]*1.08);
printf("weight %-7.2f%-7.2f%-7.2f%-10.2f%-7.2f\n",a[0],a[1],a[2],a[3],a[0]+a[1]+a[2]+a[3]);
}
return 0;
}
37 求奇数的乘积
问题描述 :
给你n个整数,求他们中所有奇数的乘积。
输入说明 :
输入数据包含两行,第一行为一个数为n,表示第二行将输入n个整数。你可以假设这n个数据中必定至少存在一个奇数。
输出说明 :
输出一个整数。
#include<stdio.h>// summershell :QA+_+AQ:
int main()//水题,和34题如出一辙
{
int n,T,sum=1;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
if(n%2==1)sum*=n;
}
printf("%d\n",sum);
return 0;
}
38 素数表
问题描述 :
从键盘输入m,n
在屏幕上按每行10个的格式输出m~n之间的全部素数。
请用函数判断一个数是否素数。
输入说明 :
两个整数m n
输出说明 :
[m,n]之间(包含m和n)的素数,每行10个,每个数后跟一个空格。
#include<stdio.h>// summershell :QA+_+AQ:
int pri[10001];
void prime()
{
for(int i=0;i<10001;i++)pri[i]=1;
pri[0]=pri[1]=0;
for(int i=2;i<10001;i++)
if(pri[i])
for(int j=i+i;j<10001;j+=i)
pri[j]=0;
}
int main()//水题,和34题如出一辙
{
int n,m,t,i;
prime();
scanf("%d %d",&n,&m);
if(n>m){t=n;n=m;m=t;}
for(i=n,t=0;i<=m;i++)
{
if(pri[i])
{
printf("%d ",i);
t++;
if(t%10==0)printf("\n");
}
}
return 0;
}
39 亲和数
问题描述 :
古希腊数学家毕达哥拉斯在自然数研究中发现,
220的所有真约数(即不是自身的约数)之和为:
1+2+4+5+10+11+20+22+44+55+110=284。
而284的所有真约数为1、2、4、71、 142,加起来恰好为220。
人们对这样的数感到很惊奇,并称之为亲和数。
一般地讲,如果两个数中任何一个数都是另一个数的真约数之和,则这两个数就是亲和数。
你的任务就编写一个程序,判断给定的两个数是否是亲和数
输入说明 :
输入数据第一行包含一个数M,接下来有M行,每行一个实例,包含两个整数A,B; 其中 0 <= A,B <= 600000
输出说明 :
对于每个测试实例,如果A和B是亲和数的话输出YES,否则输出NO。
#include<stdio.h>// summershell
#include<math.h>
int judge(int a)
{
if(a<=1)return 0;
int t=1,i;
for(i=2;i<sqrt(a);i++)
if(a%i==0)t=t+i+a/i;
if(i==sqrt(a))t+=i;
return t;
}
int main()//水题
{
int M,A,B;
scanf("%d",&M);
while(M--)
{
scanf("%d %d",&A,&B);
printf("%s\n",(judge(A)==B && A==judge(B))?"YES":"NO");
}
return 0;
}
40 分拆素数和
问题描述 :
把一个偶数拆成两个不同素数的和,有几种拆法呢?
说明:
比如10,可以拆成3+7和5+5以及7+3,
但是3+7与7+3相同,只算一种,5+5由于两个素数相同,不计算在内。
因此,10的拆法只有一种。
输入说明 :
首先输入一个T(不超过500),然后输入T个正的偶数,其值不会超过10000。
输出说明 :
对应每个偶数,输出其拆成不同素数的个数,每个结果占一行。
#include<stdio.h>// summershell
int pri[10001],num[10001];
void prime()
{
for(int i=0;i<10001;i++)pri[i]=1;
for(int i=2,counter=0;i<10001;i++)
if(pri[i]==1)
{
num[counter++]=i;//所有的素数都放在一个数组里面
for(int j=2*i;j<10001;j+=i)
pri[j]=0;
}
}
int main()//水题
{
int M,N,counter;
prime();
scanf("%d",&M);
while(M--)
{
scanf("%d",&N);
counter=0;
for(int i=0;num[i]<N;i++)//双重遍历,暴力枚举
for(int j=i+1;num[j]<N;j++)
if(num[i]+num[j]==N)counter++;
printf("%d\n",counter);
}
return 0;
}
41 求斐波拉切数列
问题描述 :
斐波拉切数列a1, a2, …, an的定义如下: a1 = 1; a2 = 1; an = an-1 + an-2; (n > 2) 求出第n项an的值。
输入说明 :
你的程序需要从标准输入设备(通常为键盘)中读入多组测试数据。每组输入数据由一行组成,其中只有一个正整数n(0 < n ≤ 20)。两组输入数据间无空行。
输出说明 :
对每组测试数据,你的程序需要向标准输出设备(通常为启动该程序的文本终端)输出一行,其中只有一个整数,也就是an的值(我们保证它小于231),所有数据前后没有多余的空格或空行,两组数据之间也没有多余的空行。
#include<stdio.h>// :summershell
int main()//水题
{
int N,a[25]={0,1,1};
for(int i=2;i<25;i++)a[i]=a[i-1]+a[i-2];
while(scanf("%d",&N)!=EOF)printf("%d\n",a[N]);
return 0;
}
42 统计不及格人数
问题描述 :
输入某班学生某门课的成绩(最多不超过40人),用函数编程统计不及格人数并输出。
输入说明 :
分两行输入,第一行为一个非负整数n,表示该班学生人数。第二行为n个成绩(可为实数),分数之间以一个空格分隔。如果n等于0,则无第二行。
输出说明 :
输出一个整数,表示该班不及格人数。行首与行尾无多余空格。
#include<stdio.h>// summershell
int main()//水题
{
int N,cou=0;
double t;
scanf("%d",&N);
if(N!=0)
for(int i=1;i<=N;i++)
{
scanf("%lf",&t);
if(t<60)cou++;
}
printf("%d\n",cou);
return 0;
}
43 平均值问题
问题描述 :
从键盘上输入一个整数n,之后输入n 个实数,输出这n个实数的平均值,并统计平均值以上(含平均值) 的实数个数。
输入说明 :
你的程序需要从标准输入设备(通常为键盘)中读入多组测试数据。每组测试数据数据占两行,第一行表示输入数据的个数(大于零,小于等于80),第二行是输入的数据,其中每个数据都是实数。
输出说明 :
对每组测试数据,你的程序需要向标准输出文件(通常为启动该程序的终端)输出一个答案。每个答案占一行。说明:计算结果小数点后保留六位。
#include<stdio.h>// summershell
int main()//水题
{
int N;
double a[85],temp;
while(scanf("%d",&N)!=EOF)
{
int cou=0;
double sum=0.0;;
for(int i=0;i<N;i++)
{
scanf("%lf",&a[i]);
sum+=a[i];
}
temp=sum/N;
for(int i=0;i<N;i++)if(a[i]>=temp)cou++;
printf("%.6f %d\n",temp,cou);
}
return 0;
}
44 统计高于平均分人数
问题描述 :
输入某班学生某门课的成绩(最多不超过40人),当输入为负值时,表示结束输入,用函数编程统计成绩高于平均分的学生人数并输出。
输入说明 :
输入若干非负实数,表示学生成绩,成绩之间以一个空格分隔。分数的最后输入一个负数,表示输入结束(该负数不是分数)。分数最多40个。
输出说明 :
输出一个整数,表示高于平均分的人数。行首与行尾无多余空格。
#include<stdio.h>// summershell
int main()//水题
{
int cou=0,N=0;
double a[85],sum=0.0,temp;
while(scanf("%lf",&a[N])!=EOF)
{
if(a[N]<0)break;
sum+=a[N++];
}
temp=sum/N;
for(int i=0;i<N;i++)if(a[i]>temp)cou++;
printf("%d\n",cou);
return 0;
}
45 调换数组最大最小
问题描述 :
输入若干整数,用函数编程将其中最大数与最小数的位置交换,然后输出交换位置后的数组内容。
输入说明 :
分两行输入,第一行为一个非负整数n,表示将要输入的整数个数。第二行为n个整数,整数之间以一个空格分隔。2<=n<=40。
输出说明 :
输出n个整数,表示交换位置后的数组内容,整数之间以一个空格分隔。行首与行尾无多余空格。
#include<stdio.h>// summershell
int main()//水题
{
int ma=-10000000,mal=0,minl=0,mi=100000,a[85],n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
if(a[i]>ma){ma=a[i];mal=i;}
if(a[i]<mi){mi=a[i];minl=i;}
}
ma=a[minl];a[minl]=a[mal];a[mal]=ma;
for(int i=0;i<n;i++)
{
if(i!=0)printf(" ");
printf("%d",a[i]);
}
printf("\n");
return 0;
}
46 排序问题
问题描述 :
从键盘上输入一组整数,把数据由大到小排序并输出。
输入说明 :
你的程序需要从标准输入设备(通常为键盘)中读入多组测试数据。每组测试数据数据占两行,第一行表示输入数据的个数(大于零,小于80),第二行是输入的数据,其中每个数据都是整数(大于等于-231,小于等于231-1)。
输出说明 :
对每组测试数据,你的程序需要向标准输出文件(通常为启动该程序的终端)依次输出一组对应的答案。每个答案占一行,即把输入的数据由大到小排序并输出。说明:每组答案最后一个数字末尾留一个空格,最后一组答案后留一空行。
#include<stdio.h>// summershell
#include<algorithm>
int cmp(int a,int b)
{
return a>b;
}
int main()//水题
{
int a[85],n;
while(scanf("%d",&n)!=EOF)
{
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
std::sort(a,a+n,cmp);
for(int i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
}
printf("\n");
return 0;
}
47 奇偶间谍
问题描述 :
奇数和偶数正在交战,在奇数的阵营里有偶数出现就被认为是间谍,反过来也一样。
输入包含10行,请将其中的间谍数(与其他数奇偶性不同的那一个,有且仅有一个)找出来并输出。
注意,间谍可能是奇数也可能是偶数。
输入说明 :
10行,每行一个数字
输出说明 :
1行,与其他数不同的那一个
我的想法是 用flag判断 队伍中 谁多 然后相应的变换来查谁是间谍
#include<stdio.h>// summershell
int main()//水题
{
int a[20],flag=0,jiou=0;
for(int i=0;i<10;i++)
{
scanf("%d",&a[i]);
if(a[i]%2==0)flag++;
}
if(flag>=2)jiou=1;
for(int i=0;i<10;i++)
{
if(a[i]%2==jiou)printf("%d\n",a[i]);
}
return 0;
}
48 求质数(素数)个数
问题描述 :
求出所有的大于等于n小于等于m的质数,统计其数目。(n≤m)
输入说明 :
你的程序需要从标准输入设备(通常为键盘)中读入多组测试数据。每组一行,每行包含两个整数n、m(n、m都不大于20000)。两组数据之间没有多余的空行。在行首和行尾没有多余的空格。
输出说明 :
对每组测试数据,你的程序需要向标准输出设备(通常为启动该程序的终端)依次输出一组对应的答案。每组输出数据为一个整数。两组数据之间没有多余的空行。在行首和行尾没有多余的空格。
#include<stdio.h>// :summershell :QA+_+AQ:
int pri[20001],visit[20001];
void prime()
{
for(int i=0;i<20001;i++)pri[i]=1;
pri[0]=pri[1]=visit[0]=visit[1]=0;
for(int i=2,cou=2;i<20001;i++)
{
if(pri[i])
{
visit[cou]=visit[cou-1]+1;
for(int j=i+i;j<20001;j+=i)
pri[j]=0;
}
else visit[cou]=visit[cou-1];
cou++;
}
}
int main()//水题,和34,38题如出一辙
{
int n,m;
prime();
while(scanf("%d %d",&n,&m)!=EOF)
{
printf("%d\n",visit[m]-visit[n]+pri[n]);;
}
return 0;
}
49 卖鸭子
问题描述 :
有一个养鸭专业户,赶了一大群鸭子出去卖。他每经过一个村庄,卖出当时所有赶的鸭子的一半再多一只(他没有劈开过鸭子…),这样他经过七个村庄后,还剩下两只鸭子,那么请算一下他经过第N个村庄时卖出多少只鸭子,还有多少只鸭子。
输入说明 :
你的程序需要从标准输入设备(通常为键盘)中读入多组测试数据。每组一行,每行数据包含一个整数N,1≤N≤7。两组数据之间没有多余的空行。在行首和行尾没有多余的空格。
输出说明 :
对每组测试数据,你的程序需要向标准输出设备(通常为启动该程序的终端)依次输出一组对应的答案。每组输出数据由一行组成,该行中包含两个整数,第一个代表在第N个村庄卖出了多少鸭子,第二个代表还剩下多少鸭子。两组数据之间也没有多余的空行。在行首和行尾没有多余的空格。
Solution:
我是采用的倒推 数组存放的是还剩多少 所以卖出的要+2
#include<stdio.h>// :summershell :Q+_+Q:
int main()//水题,倒推
{
int a[20]={0,2},N;
for(int i=2;i<10;i++)a[i]=(a[i-1]+1)*2;
while(scanf("%d",&N)!=EOF)printf("%d %d\n",a[8-N]+2,a[8-N]);
return 0;
}
50 输出正整数对应的二进制数
问题描述 :
输入一个十进制正整数,输出它的二进制数。
输入说明 :
你的程序需要从标准输入设备(通常为键盘)中读入多组测试数据。每组输入数据由一行组成,其中包含一个正整数n,0≤n≤1024,所有数据前后没有多余的空格,两组数据之间也没有多余的空行。
输出说明 :
对每组测试数据,你的程序需要向标准输出设备(通常为启动该程序的终端)依次输出一组对应的答案。每组输出数据由一行组成,包含输入整数对应的二进制数,所有数据前后没有多余的空格,两组数据之间也没有多余的空行。
Caution:
0要特判一下
#include<stdio.h>// summershell
int main()//水题,倒排取余法
{
int N,sta[100],top=-1;
while(scanf("%d",&N)!=EOF)
{
if(N==0)printf("0");
while(N)
{
sta[++top]=N%2;
N/=2;
}
while(top!=-1)printf("%d",sta[top--]);
printf("\n");
}
return 0;
}
51 开关灯
问题描述 :
有N个灯放在一排,从1到N依次顺序编号。有N个人也从1到N依次顺序编号。1号将灯全部关闭,然后2将凡是2的倍数的灯打开;3号将凡是3的倍数的灯做相反处理(该灯如为打开的,则将它关闭;如关闭的,则将它打开)。以后的人都和3号一样,将凡是自己标号倍数的灯做相反处理。试计算第N个人操作后,哪些灯是点亮的。(1表示点亮,0表示关闭)
输入说明 :
你的程序需要从标准输入设备(通常为键盘)中读入多组测试数据。每组输入数据占一行,每行数据输入一个N,0<N≤20。在行首和行尾没有多余的空格。
输出说明 :
对每组测试数据,你的程序需要向标准输出设备(通常为启动该程序的文本终端,例如你在Windows中启动该程序所用的命令行终端)依次输出从标准输入设备中读入的每一组测试数据对应的结果,所有数据前后没有多余的空行,两组数据之间也没有多余的空行。每组输出数据由一行组成,该行中包含N个0,1,代表最终时所有灯的状态。在行首和行尾没有多余的空格。
Solution:
可以发现 第1个人打开后 后面的人就做相反处理了 那么1和-1就可以变换了
#include<stdio.h>// :summershell
int main()//水题
{
int N,a[100];//0多不好算,-1多好
for(int i=0;i<100;i++)a[i]=-1;
for(int i=2;i<100;i++)
for(int j=i;j<100;j+=i)a[j]*=-1;
while(scanf("%d",&N)!=EOF)
{
for(int i=1;i<=N;i++)printf("%d",a[i]==-1?0:1);
printf("\n");
}
return 0;
}
52 回文平方数
问题描述 :
回文数是指从左向右念和从右向左念都一样的数。如12321就是一个典型的回文数。 给定一个进制B(2=<B<=20进制),输出所有的大于等于1小于等于300且该数的平方用B进制表示时是回文数的数(该数本身不要求是回文数)。
输入说明 :
共一行,一个单独的整数B(B用十进制表示,比如18)。
输出说明 :
每行两个数字,第二个数是第一个数的平方,且第二个数是回文数。
注意:输出时,这两个数都应该以B进制表示。
在输出时,数字10到20分别以A到K代替。
Caution:
写一个转换进制后打印的函数就行了 然后判断回文时候再来一个函数
#include<stdio.h>// :summershell
int huiwen(int a,int B)//判断n*n转成B进制后是否回文
{
int t=a,top=-1,sta[100]={0,0};
while(t)
{
sta[++top]=t%B;
t/=B;
}
for(t=0;t<=top/2;t++)if(sta[t]!=sta[top-t])return 0;
return 1;
}
void print(int a,int B)
{
int t=a,top=-1,sta[100];
while(t)
{
sta[++top]=t%B;
t/=B;
}
while(top!=-1)//利用栈倒排
if(sta[top]<10)printf("%d",sta[top--]);
else printf("%c",sta[top--]-10+'A');
}
int main()//水题
{
int B;
while(scanf("%d",&B)!=EOF)
{
for(int i=1;i<=300;i++)
{
if(huiwen(i*i,B))
{
print(i,B);
printf(" ");
print(i*i,B);
printf("\n");
}
}
}
return 0;
}
53 进制转换
问题描述 :
输入一个十进制数N,将它转换成R进制数输出。
输入说明 :
输入数据包含T个测试实例,每个测试实例包含两个整数N(32位整数,可为负数)和R(2<=R<=16, R<>10)。
输出说明 :
为每个测试实例输出转换后的数,每个输出占一行。如果R大于10,则对应的数字规则参考16进制(比如,10用A表示,等等)。
Solution:
用上一题的模板 它不香吗
#include<stdio.h>// summershell
void zhuan(int a,int B)
{
if(a==0)printf("0");
int t=a,top=-1,sta[100];
while(t)
{
sta[++top]=t%B;
t/=B;
}
while(top!=-1)//利用栈倒排
if(sta[top]<10)printf("%d",sta[top--]);
else printf("%c",sta[top--]-10+'A');
}
int main()//水题,利用52题的余热发挥下
{
int T,temp,R;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&temp,&R);
if(temp<0){printf("-");temp*=-1;}
zhuan(temp,R);
printf("\n");
}
return 0;
}
54 删除数组元素
问题描述 :
已有一维数组,存储不超过100个整型数据,由用户输入一个元素值,从数组中删除与该值相等的所有元素(考虑到元素值可能重复,因此可能删除多个元素),并输出结果数组。
输入说明 :
用户可输入多组数据,每组数据由三行组成:
第一行:数组元素的个数n
第二行:n个数组元素,由空格分隔
第三行:需要删除的元素
输出说明 :
对于每组输入,输出最后的结果,整数之间以空格分隔。每行的开头与结尾无多余空格。
每组输出占一行。
如果结果数组为空,则输出“Empty array!”。
#include<stdio.h>// summershell
int main()//水题
{
int N,a[200],del,t,i;
while(scanf("%d",&N)!=EOF)
{
for(i=0;i<N;i++)scanf("%d",&a[i]);
scanf("%d",&del);
for(i=0,t=0;i<N;i++)if(a[i]!=del)a[t++]=a[i];
if(t==0)printf("Empty array!");
else for(i=0;i<t;i++)printf(i==0?"%d":" %d",a[i]);
printf("\n");
}
return 0;
}
55 删除数组重复元素
问题描述 :
已有一维数组,存储不超过100个整型数据,其中有些元素的值存在重复,从数组中删除所有重复的元素(每个元素只保留一个),并输出结果数组。
输入说明 :
用户可输入多组数据,每组数据由两行组成:
第一行:数组元素的个数n
第二行:n个数组元素,由空格分隔
输出说明 :
对于每组输入,输出最后的结果,整数之间以空格分隔。每行的开头与结尾无多余空格。
每组输出占一行。
#include<stdio.h>// summershell
int main()//水题
{
int N,a[200],t,i,j;
while(scanf("%d",&N)!=EOF)
{
for(i=0;i<N;i++)scanf("%d",&a[i]);
for(i=0,t=0;i<N;i++)//类似于插入排序,分为前后两个表
{//题上没说出现重复后删掉哪个?所以我选择删掉后面的
for(j=0;j<i;j++)if(a[j]==a[i])break;
if(j>=i)a[t++]=a[i];
}
for(i=0;i<t;i++)printf(i==0?"%d":" %d",a[i]);
printf("\n");
}
return 0;
}
56 循环数组
问题描述 :
编写程序,将一维数组中的元素向右循环移动N次。
输入说明 :
第一行整数n,表示数组大小为n
第二行,n个数,表示数组中的n个元素。
第三行,整数N,表示数组向右移动N次。
输出说明 :
移动后的数组元素,每两个元素之间以一个空格分隔。行首与行尾无多余空格。
Solution:
408真题 且r要优化一下 不然出错
#include<stdio.h>// summershell
void rever(int a[],int l,int r)
{
for(int i=l,t;i<=(l+r)/2;i++){t=a[i];a[i]=a[l+r-i];a[l+r-i]=t;}
}
int main()//这不是408的真题吗?分为两个子表逆置即可
{
int N,r,i,a[1000];
while(scanf("%d",&N)!=EOF)
{
for(i=0;i<N;i++)
scanf("%d",&a[i]);
scanf("%d",&r);
r=r%N; //防止r过大,出现非法下标
rever(a,0,N-r-1);
rever(a,N-r,N-1);
rever(a,0,N-1);
for(i=0;i<N;i++)printf(i==0?"%d":" %d",a[i]);
printf("\n");
}
return 0;
}
57 斐波那契部分和
问题描述 :
计算闭区间[m,n](即大于等于m且小于等于n)内的所有斐波那契数的和。
要求定义并调用函数fib(n),它的功能是返回第n项Fibonacci数。
例如,fib(7)返回13
Fibonacci={1,1,2,3,5,8,13,................}
其中:an=an-1+an-2
输入说明 :
两个数m和n
输出说明 :
所有属于闭区间[m,n]即大于等于m,小于等于n的斐波那契数的和。
Idea:
先存好数列 然后定位n和m
#include<stdio.h>// summershell
int main()//水题
{
int m,n,a[1001]={0,1,1};
for(int i=3;i<1001;i++)a[i]=a[i-1]+a[i-2];
while(scanf("%d %d",&m,&n)!=EOF)
{
int sum=0,i=0;
while(a[i]<m)++i;
while(a[i]<=n){sum+=a[i];i++;}
printf("%d\n",sum);
}
return 0;
}
58 杨辉三角
问题描述 :
还记得中学时候学过的杨辉三角吗?
基本的特征是:
前提:端点的数为1.
- 每个数等于它上方两数之和。
- 每行数字左右对称,由1开始逐渐变大。
- 第n行的数字有n项。
你可以参考以下的图形:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
1 11 55 165 330 462 462 330 165 55 11 1
1 12 66 220 495 792 924 792 495 220 66 12 1
...
输入说明 :
输入数据首先包含一个正整数T ( T < 10 ),表示有 T 组测试数据, 每组测试数据只包含一个正整数n(1 <= n <= 20),表示将要输出的杨辉三角的层数。
输出说明 :
对应于每一个输入,请输出相应层数的杨辉三角,输出的整数之间用一个空格隔开,每一个杨辉三角后面加一个空行。
输出时,每一行的开头的“1”前面不需要空格,结尾的“1”后面也没有空格。
#include<stdio.h>// summershell
int main()//水题
{
int n,a[25][25],T;
for(int i=1;i<25;i++)
for(int j=1;j<=i;j++)
if(j==1 || j==i)a[i][j]=1;
else a[i][j]=a[i-1][j-1]+a[i-1][j];
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=i;j++)
printf(j==1?"%d":" %d",a[i][j]);
printf("\n");
}
printf("\n");
}
return 0;
}
59 数字金字塔
问题描述 :
考虑在下面被显示的数字金字塔(第n行有n列)。写一个程序来计算从最高点开始在底部任意处结束的路径经过数字的和的最大。每前进一步可以走到它的正下方或者右下方(往下一行、往右一列)的位置。
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
在上面的样例中,从7 到 3 到 8 到 7 到 5 的路径产生了最大和:30
输入说明 :
第一个行包含 R(1<= R<=1000) ,表示行的数目。后面每行为这个数字金字塔特定行包含的整数。所有的被供应的整数是非负的且不大于100。
输出说明 :
输出仅一行,包含那个可能得到的最大的和。
Solution:
动态规划的题目 也可以从最下面一层开始 然后每次取下方或者右下方的较大值加上去
#include<stdio.h>// summershell
int maxcmp(int a,int b)
{
return a>b?a:b;
}
int main()//简单dp,可以自上往下,用数组暂存当前最大值
{
int n,a[102][102],b[102][102];
while(scanf("%d",&n)!=EOF)
{
int maxnum=-100;
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
{
scanf("%d",&a[i][j]);
b[i][j]=a[i][j];
}
for(int i=2;i<=n;i++)
for(int j=1;j<=i;j++)
if(j==1)b[i][j]+=b[i-1][j];
else if(j==i)b[i][j]+=b[i-1][j-1];
else b[i][j]+=maxcmp(b[i-1][j],b[i-1][j-1]);
for(int i=1;i<=n;i++)if(maxnum<b[n][i])maxnum=b[n][i];
printf("%d\n",maxnum);
}
return 0;
}
60 发牌
问题描述 :
编制一个模拟发牌的程序。有编号为1,2,3,4四个人,将一付去掉大小怪的扑克按照如下顺序排列梅花c0-c12,方块d0-d12,红桃h0–h12,黑桃s0-s12,然后按照1,2,3,4四个人的顺序发牌,问最后每个人手上的牌有哪些。
输入说明 :
你的程序需要从标准输入设备(通常为键盘)中读入多组测试数据。每组输入数据由一行组成。每组数据包含一个在1到4之间的整数,代表四个人中的一个,在行首和行尾没有多余的空格。
输出说明 :
对每组测试数据,你的程序需要向标准输出设备(通常为启动该程序的终端)依次输出一组对应的答案。对于每组输入,输出那个人手上的牌。每组一行。每行包括13张牌,每张牌由牌的花色和牌的大小组成。牌的花色和牌的大小之间有一个空格,前后两张牌之间也有一个空格。其余数据前后没有多余的空格,两组数据之间也没有多余的空行。
#include<stdio.h>// summershell
int main()//简单模拟
{
int n;
while(scanf("%d",&n)!=EOF)
{//是不是很暴力?
if(n==1)printf("c 0 c 4 c 8 c 12 d 3 d 7 d 11 h 2 h 6 h 10 s 1 s 5 s 9\n");
else if(n==2)printf("c 1 c 5 c 9 d 0 d 4 d 8 d 12 h 3 h 7 h 11 s 2 s 6 s 10\n");
else if(n==3)printf("c 2 c 6 c 10 d 1 d 5 d 9 h 0 h 4 h 8 h 12 s 3 s 7 s 11\n");
else if(n==4)printf("c 3 c 7 c 11 d 2 d 6 d 10 h 1 h 5 h 9 s 0 s 4 s 8 s 12\n");
}
return 0;
}