清华计算机系研究生考试上机07年试题解答(自己今天上午做的,有一个不能完成所有测试用例~)...

清华大学计算机科学与技术系

2007 年硕士研究生招生复试

2007 3 24

注意事项:

1. 试题共三题,总计 100 分,考试时间为一个半小时。

2. 不得使用自带的电子设备,包括笔记本、 U 盘、手机等;不得使用参考书籍和资料。

3. 编程环境为 Windows 2000 Professional + Visual Studio 6.0 ,只能使用 C/C++ 语言。

4. 每一题的输入数据都从文件 input.txt 中读取,将结果输出至文件 output.txt 请严格按照每一题的输入输出格式 。在考试过程中,我们恕不提供除试题中样例以外的测试数据,请自行生成输入数据以对程序进行自测。

5. 在考试结束之前自行设置编译环境和配置编译参数,将所写的程序编译成可执行文件,文件名在每一题中都有规定。生成的可执行文件将作为最终测试的唯一依据 ,若无法运行您的可执行文件,最终成绩将记为零分。

6. 程序对每个测试数据的可用运行时间上限 1 秒,若超时或结果错误,则该测试用例不能得分。

7. 在考试过程中,若计算机出现故障,请及时通知工作人员,以免耽误您的考试时间。

8. 上机考试结束后,请勿马上离开,工作人员将会直接进行现场测试,需要您的合作。

第一题(可执行文件名 program1.exe

求正整数 N(N>1) 的质因数的个数。注意: 1 不是 N 的质因数:若 N 为质数, N N 的质因数。相同的质因数需要重复计算。

120=2*2*2*3*5 ,共有 5 个质因数。

输入:

正整数N1<N<109

输出:

N 的质因数的个数

样例输入:

120

样例输出

5

5 #include<stdlib.h> #include<stdio.h> #include<math.h> int main(void) { int i=2,count=1; long int N; char buffer[10]; FILE *fp1,*fp2; fp1=fopen("input","r"); fgets(buffer,10,fp1); N=atol(buffer); while(i<=sqrt(N)) { for(;i<=sqrt(N);i++) if(N%i==0) { N=N/i; printf("%d*",i); count++; break; } } printf("%d",N); fp2=fopen("output","w"); itoa(count,buffer,10); fputs(buffer,fp2); rewind(fp2); fclose(fp1); fclose(fp2); return 0; }

第二题(可执行文件名:program2.exe

对于一个十进制数A ,将A 转换为二进制数,然后按位逆序排列,再转换为十进制数B ,我们乘BA二进制逆序数

例如对于十进制数173 ,它的二进制形式为101011101 ,逆序排列得到10110101 ,其十进制数为181181 即为173 的二进制逆序数

输入:

一个1000(2999 ) 以内的十进制数。

输出:

输入的十进制数的二进制逆序数。

样例输入:

173

样例输出:

181

(下列程序只能忍受部分测试用例)

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #define MAX 100 #define LEN 1000 long int process(long int N) { long int M=0; int count=0; int i,j; int temp[LEN]; int *p=temp; int tempr[LEN]; int *r=tempr; long int tmpnumber=N; for(i=0;tmpnumber!=0;tmpnumber/=2,i++) { *p++=tmpnumber%2; *r++=pow(2,i); count++; } for(i=0,j=count-1;i<count;i++,j--) { printf("temp[i]*tempr[j]=%d\n",temp[i]*tempr[j]); M+=temp[i]*tempr[j]; } return M; } int main(void) { long int N,M; FILE *fp1,*fp2; char buffer[MAX]; fp1=fopen("input","r"); fgets(buffer,MAX,fp1); N=atol(buffer); M=process(N); fp2=fopen("output","w"); ltoa(M,buffer,10); fputs(buffer,fp2); fclose(fp1); fclose(fp2); return 0; }

第三题(可执行文件名program3.exe

有若干张邮票,要求从中选取最少的邮票张数凑成一个给定的总值。

如,有1 分,3 分,3 分,3 分,4 分五张邮票,要求凑成10 分,则使用3 张邮票:3 分、3 分、4 分即可。

输入:

首先是要求凑成的邮票总值MM<100

然后是一个数NN20 ,表示有N 张邮票。接下来是N 个正整数,分别表示这N 张邮票的面值,且以升序排列。

输出:

能够凑成总值M 的最少邮票张数。若无解,输出0

样例输入:

10 5 1 3 3 3 4

样例输出:

3

分析:这是最简单的背包问题,动态规划的方法,写得不是很规范,不过结果很不错,线形复杂度 ~~

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #define MAX 100 #define LEN 1000 void process(int M,int *a,int offset,int *flag) { if(offset>=0) { if(M-a[offset]>0) { if((M-a[offset])>=a[offset-1]) { flag[offset]=1; if(M>=0) process(M-a[offset],a,offset-1,flag); } else { if(M>=0) process(M,a,offset-1,flag); } } else if(M-a[offset]==0) flag[offset]=1; } } int main(void) { int N,M,i,number=0; int result; int count=0; FILE *fp1,*fp2; char tmp; int value[MAX]; int option[MAX]; int *p=value; int *flag=option; fp1=fopen("input","r"); fscanf(fp1,"%d %d",&M,&N); printf("M=%d,N=%d\n",M,N); for(i=0;i<N;i++) { fgetc(fp1); tmp=fgetc(fp1); value[i]=atoi(&tmp); printf("value=%d\n",value[i]); } process(M,p,N-1,flag); for(i=0;i<N;i++) { if(*flag++==1) { printf("%d",value[i]); count+=value[i]; number++; } } result=(count==M?number:0); fp2=fopen("output","w"); fprintf(fp2,"%d",result); fclose(fp1); fclose(fp2); return 0; }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值