c语言复赛题

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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种组合情况,计算出其中的最大价值组合,就是本题的算法

相关文档
最新文档