c语言复赛题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
信息学奥赛复赛练习题
1.模拟开关(题目名称: moni.bas)(12分)
[题目描述]:有N盏电灯排成一行,依次编号为1,2,3,…,N。现各有一个开关,开始灯都亮着的。现在还有N个人,第一人走过来依次把1和1的倍数电灯的开关都拉一下。第三个人走过来依次把3和3的倍数的开关都拉一下,第五个人走过来依次把5和5的倍数的开关都拉一下(按奇数的规律),…问最后都有哪些灯是关着的?
[输入文件] 文件名:moni.in
文件中只有一行,包含1个整数N(其中5≤N≤30)
[输出文件] 文件名:moni.out
文件中共有若干行,每一行一个数据,分别为那些关着的灯泡的编号。
要求:每一行的输出数据都从第一列开始。
[样例输入]:moni.in的内容为:
10
[样例输出]:moni.out的内容为:
1
2
4
8
9
main()
{
int i,n,s,x;
int a[1000];
scanf("%d",&n);
for(i=1;i a[i]=1; x=1; while(x<=n) { s=0; while(s<=n) {s=s+x; a[s]=1-a[s]; } x=x+2; } s=0; for(i=1;i if(a[i]==0) {printf("%d ",i);s=s+1; } if(s==0) printf("0"); } 3.【问题描述-明明的随机数】 明明想在学校中请一些同学一起做问卷调查,为了实验的客观性,他先用计算机生成了 N 个1 到1000 之间的随机整数,(N≤100),对于其中重复的数字,只保留一个,把其余相 同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好 输入文件random.in 有2 行,第1 行为1 个正整数,表示所生成的随机数的个数:N 第二行有N 个用空格隔开的正整数,为所产生的随机数。 【输出文件】 输出文件random.out 也是2 行,第1 行为1 个正整数M,表示不相同的随机数的个数。 第2 行为M 个用空格隔开的正整数,为从小到大排好序的不相同的随机数。 【输入样例】 10 20 40 32 67 40 20 89 300 400 15 【输出样例】 8 15 20 32 40 67 89 300 400 /*本题主要是考察对排序算法的掌握,只不过外加了一个去重的操作。本题的算法有很多,我们在考试时,时间紧,题目难度大。如果我们能用最简单的思维方式解决问题的话,就不一定把很多的时间放在代码执行效率的优化问题上。有时候牺牲一点空间(内存)和时间对于获取更多的考试时间是非常有必要的。本题最简单的思想方法,就是根据题目要求,先对给定的一组数据进行排序,排序的方法可以使用最简单的冒泡算法来完成。由于本题的输出结果要求我们必须先统计出不重复数据的个数,所以当数据排序之后,我们可以先对所有的数据遍历一次,这一次遍历的目的就是让我们统计出不重复数据的个数,并将其输出。最后,我们还需进行一次遍历,这次遍历用于打印出排序之后不重复的所有数据结果. */ #include int main() { FILE *fp1,*fp2; int N,M=0; int i,j; int a; int num[100]; //根据题目所给的数据规模定义数组的大小 if((fp1=fopen("random.in","r"))==NULL) { printf("cannot open file\n"); return 0; } fscanf(fp1,"%d",&N); //输入随机数的个数 for(i=0;i fscanf(fp1,"%d",&num[i]); //将已知的随机数存放到初始数组中 for(i=0;i for(j=i+1;j { if(num[i]>num[j]) { a=num[i]; num[i]=num[j]; num[j]=a; } } fp2=fopen("random.out","w"); //打开写文件的指针 { if(i>0&&num[i]==num[i-1]) //思考一下这个去重的操作中为什么有i>0这个条件 continue; M++; } fprintf(fp2,"%d\n",M); //在结果文件中打印出不重复数据的个数并键入一个回车符 for(i=0;i { if(i>0&&num[i]==num[i-1]) //思考一下这个去重的操作中为什么有i>0这个条件 continue; fprintf(fp2,"%d ",num[i]); } fclose(fp1); fclose(fp2); return 0; } 4.【问题描述-开心的金明】 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N 元钱就行”。今天一早金明就开始做预算,但是他想买的东西太多了,肯定会超过妈妈限定的N 元。于是,他把每件物品规定了一个重要度,分为5 等:用整数1~5 表示,第5 等最重要。他还从因特网上查到了每件物品的价格(都是整数元)。他希望在不超过N 元(可以等于N 元)的前提下,使每件物品的价格与重要度的乘积的总和最大。设第j 件物品的价格为v[j],重要度为w[j],共选中了k 件物品,编号依次为, j1,j2,……jk ,则所求的总和为:v[j1]*w[j1]+v[j2]*w[j2]+……+v[jk]*w[jk] (其中*为乘号) 请你帮助金明设计一个满足要求的购物单。 【输入文件】 输入文件happy.in 的第1 行,为两个正整数,用一个空格隔开: N m (其中N(<30000)表示总钱数,m(<25)为希望购买物品的个数。) 从第2 行到第m+1 行,第j 行给出了编号为j-1的物品的基本数据,每行有2 个非负整数 v p (其中v 表示该物品的价格(v≤10000),p 表示该物品的重要度(1-5)) 【输出文件】 输出文件happy.out 只有一个正整数,为不超过总钱数的物品的价格与重要度乘积的总和的最大值(<100000000) 【输入样例】 1000 5 800 2 400 5 300 5 400 3 200 2 【输出样例】 3900 背包问题的解决办法有很多,但是都不太容易理解,本算法采用穷举法结合二进制数据的排列来穷举所有价值组合 主要思想: 根据物品的个数先计算出所有物品排列组合的排列数,每件物品取为1,不取为0 假设用n个物品,从n个物品中任意取出若干个的最大组合次数为:2^n-1种,因此只要穷举出2^n-1种组合情况,计算出其中的最大价值组合,就是本题的算法