清华大学 2006年机试题

题目1076:N的阶乘

题目描述:

输入一个正整数N,输出N的阶乘。

输入:

正整数N(0<=N<=1000)

输出:

输入可能包括多组数据,对于每一组输入数据,输出N的阶乘

样例输入:
4
5
15
样例输出:
24
120
1307674368000

该题考察长整数乘法开始的代码是这样的
 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <string>
 5 #define MAX 3002
 6 int ans[MAX];
 7 int len;
 8 int ans2[MAX];
 9
10 void cal(int m) {
11     int ci = 0;
12     int q;
13     int pm = -1;
14     int len2 = len;
15     memset(ans2,0,sizeof(ans2));
16     while(m != 0) {
17         int tempM = m % 10;
18         pm++;
19         q = pm;
20         for(int i = 0; i < len; i++) {
21             int tempSum = ans[i] * tempM  + ci + ans2[q];
22             int tempBen = (tempSum) % 10;
23             ci = (tempSum) / 10;
24             ans2[q] = tempBen;
25             q++;
26         }
27         while(ci != 0) {
28             int bt = ci % 10;
29             ans2[q] = ans2[q] + bt;
30             q++;
31             ci = ci/10;
32         }
33         len2 = q;
34         m = m/10;
35     }
36     for(int i = 0; i < len2; i++) {
37         ans[i] = ans2[i];
38     }
39     len = len2;
40 }
41
42 void show() {
43     for(int i = len-1; i >= 0; i--) {
44         printf("%d",ans[i]);
45     }
46     printf("\n");
47 }
48
49 int main(int argc, char const *argv[])
50  {
51     int n;
52     while(scanf("%d",&n) != EOF) {
53         if(n == 0 || n == 1) {
54             puts("1");
55             continue;
56         }
57         memset(ans,0,sizeof(ans));
58         ans[0] = 1;
59         len = 1;
60         for(int i = 2; i <= n; i++) {
61             cal(i);
62         }
63         show();
64     }
65     return 0;
66  } 

可是超时了,观察到题目所要求的内存范围比较大,修改为如下代码:

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <string>
 5 #define MAX 3002
 6
 7
 8 int ansn[1002][MAX];
 9 int lenn[1002];
10
11 void cal2(int m) {
12     int ci = 0;
13     int q;
14     int pm = -1;
15     memset(&ansn[m],0,sizeof(&ansn[m]));
16     int mo = m;
17     while(mo != 0) {
18         int tempM = mo % 10;
19         pm++;
20         q = pm;
21         for(int i = 0; i < lenn[m-1]; i++) {
22             int tempSum = ansn[m-1][i] * tempM  + ci + ansn[m][q];
23             int tempBen = (tempSum) % 10;
24             ci = (tempSum) / 10;
25             ansn[m][q] = tempBen;
26             q++;
27         }
28         while(ci != 0) {
29             int bt = ci % 10;
30             ansn[m][q] = ansn[m][q] + bt;
31             q++;
32             ci = ci/10;
33         }
34         lenn[m] = q;
35         mo = mo/10;
36     }
37
38 }
39
40
41 void show(int m) {
42     for(int i = lenn[m]-1; i >= 0; i--) {
43         printf("%d",ansn[m][i]);
44     }
45     printf("\n");
46 }
47
48 int main(int argc, char const *argv[])
49  {
50     int n;
51     memset(&ansn[1],0,sizeof(&ansn[1]));
52     ansn[1][0] = 1;
53     lenn[1] = 1;
54     for(int i = 2; i <= 1000; i++) {
55         cal2(i);
56     }
57     while(scanf("%d",&n) != EOF) {
58         if(n == 0 || n == 1) {
59             puts("1");
60             continue;
61         }
62
63         show(n);
64     }
65     return 0;
66  } 

提交成功,但内存几乎要达到上限

下面做出如下改进,首先,计算乘法时不需要把m的每一位都拆出来再乘,可以直接乘m,对结果不影响,修改为如下代码

其次,存储时也没必要每一位用一个int来存,一个int完全可以存多位,以此减少内存消耗

代码如下

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <string>
 5 #define MAX 502
 6 #define BASE 1000000
 7
 8 int ansn[1002][MAX];
 9 int lenn[1002];
10
11 void cal2(int m) {
12     int ci = 0;
13     memset(&ansn[m],0,sizeof(&ansn[m]));
14
15     int q = 0;
16     for(int i = 0; i < lenn[m-1]; i++) {
17         int tempSum = ansn[m-1][i] * m  + ci ;
18         int tempBen = (tempSum) % BASE;
19         ci = (tempSum) / BASE;
20         ansn[m][q] = tempBen;
21         q++;
22     }
23     while(ci != 0) {
24         int bt = ci % BASE;
25         ansn[m][q] = bt;
26         q++;
27         ci = ci/BASE;
28     }
29     lenn[m] = q;
30 }
31
32
33 void show(int m) {
34     printf("%d",ansn[m][lenn[m]-1]);
35     for(int i = lenn[m]-2; i >= 0; i--) {
36         printf("%06d",ansn[m][i]);
37     }
38     printf("\n");
39 }
40
41 int main(int argc, char const *argv[])
42  {
43     int n;
44     memset(&ansn[1],0,sizeof(&ansn[1]));
45     ansn[1][0] = 1;
46     lenn[1] = 1;
47     for(int i = 2; i <= 1000; i++) {
48         cal2(i);
49     }
50     while(scanf("%d",&n) != EOF) {
51         if(n == 0 || n == 1) {
52             puts("1");
53             continue;
54         }
55
56         show(n);
57     }
58     return 0;
59  } 

题目1077:最大序列和

题目描述:

给出一个整数序列S,其中有N个数,定义其中一个非空连续子序列T中所有数的和为T的“序列和”。
对于S的所有非空连续子序列T,求最大的序列和。
变量条件:N为正整数,N≤1000000,结果序列和在范围(-2^63,2^63-1)以内。

输入:

第一行为一个正整数N,第二行为N个整数,表示序列中的数。

输出:

输入可能包括多组数据,对于每一组输入数据,
仅输出一个数,表示最大序列和。

样例输入:
5
1 5 -3 2 4

6
1 -2 3 4 -10 6

4
-3 -1 -2 -5
样例输出:
9
7
-1

这是一道经典题,代码如下
 1 #include <cstdio>
 2 #include <cstdlib>
 3 int main(int argc, char const *argv[])
 4  {
 5     long long int n;
 6
 7     while(scanf("%lld",&n) != EOF) {
 8         long long int max;
 9         long long int sum;
10         long long int temp;
11
12         scanf("%lld",&temp);
13         max = temp;
14         sum = temp;
15
16         if(sum < 0) {
17             sum = 0;
18         }
19
20         for(long long int i = 1; i < n; i++) {
21             scanf("%lld",&temp);
22             sum = sum + temp;
23
24             if(max < sum) {
25                 max = sum;
26             }
27
28             if(sum < 0) {
29                 sum = 0;
30             }
31         }
32
33         printf("%lld\n", max);
34     }
35     return 0;
36  } 

题目1078:二叉树遍历

题目描述:

二叉树的前序、中序、后序遍历的定义:
前序遍历:对任一子树,先访问跟,然后遍历其左子树,最后遍历其右子树;
中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树;
后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根。
给定一棵二叉树的前序遍历和中序遍历,求其后序遍历(提示:给定前序遍历与中序遍历能够唯一确定后序遍历)。

输入:

两个字符串,其长度n均小于等于26。
第一行为前序遍历,第二行为中序遍历。
二叉树中的结点名称以大写字母表示:A,B,C....最多26个结点。

输出:

输入样例可能有多组,对于每组测试样例,
输出一行,为后序遍历的字符串。

样例输入:
ABC
BAC
FDXEAG
XDEFAG
样例输出:
BCA
XEDGAF

这道题也费了我一番功夫,主要用递归来解题时要考虑到左子树或右子树不存在的情况
 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <string>
 5
 6 #define MAX 30
 7
 8 char front[MAX];
 9 char middle[MAX];
10
11 void backOut(int start, int end, int fb) {
12     if(start == end) {
13         printf("%c",front[fb]);
14         return;
15     }
16     int wei;
17     for(int i = start; i <= end; i++) {
18         if(middle[i] == front[fb]) {
19             wei = i;
20             break;
21         }
22     }
23     //only right
24     if(wei == start) {
25         backOut(wei+1,end, wei-start+fb+1);
26     }//only left
27     else if(wei == end) {
28         backOut(start, wei-1, fb+1);
29     }
30     else {
31         backOut(start, wei-1, fb+1);
32         backOut(wei+1,end, wei-start+fb+1);
33     }
34     printf("%c",front[fb]);
35 }
36
37 int main(int argc, char const *argv[])
38  {
39
40     while(scanf("%s %s",front,middle) != EOF) {
41         backOut(0, strlen(front)-1, 0);
42         printf("\n");
43     }
44     return 0;
45  } 

时间: 2024-10-09 13:47:05

清华大学 2006年机试题的相关文章

清华大学软件2014机试

清华大学软件2014机试 By 钟桓 9月 24 2014 更新日期:9月 24 2014 今天刚刚机试完,乘者还没忘记,把自己知道的记下来,也算是泽被后来人吧~~~ 这次的机试题,相对来说,会更简单一点,总共3题,时间是3小时. 1 超级幸运数 题目大致描述: 一个数字,若是只含有1和4,这个数字就是幸运数,例如,14,114.但是514这样的就不是了,因为含有其它数字. 若这个幸运数字中,1和4的数量相同,那么就是超级幸运数,例如14,1144,41等等. 题目要求,输入一个n,n的范围是[

华为的一道机试题--等式变换

华为的一道机试题 (http://blog.csdn.net/zombie_slicer/article/details/37346025) 第三题:等式变换 输入一个正整数X,在下面的等式左边的数字之间添加+号或者-号,使得等式成立. 1 2 3 4 5 6 7 8 9 = X 比如: 12-34+5-67+89 = 5 1+23+4-5+6-7-8-9 = 5 请编写程序,统计满足输入整数的所有整数个数. 输入:       正整数,等式右边的数字 输出:       使该等式成立的个数 样

ASPNET服务端控件练习(一个机试题)

简单记录: 模糊查询的select语句的拼写 public List<Model.Student> GetWhereStudent(string name, string sub, string isG) { List<Web.Model.Student> lt = new List<Model.Student>(); string sql = "select * from SC_Student where studentName like @n and [e

华为2014机试题(一)

过几天就要进行华为的机试了,今儿临时抱抱佛脚,在网上找到2014届华为校招的机试题,琢磨了一会儿,贴出来记录下. 首先感谢一下Hackbuteer提供的题目:http://blog.csdn.net/hackbuteer1/article/details/11132567 对于第一题,字符过滤.最简单也是最直接的就是HASH.题目规定了输入序列只能为小写字符'a~z'.因此直接开辟一个大小为26的数组用于记录当前字符是否已经出现即可. 需要注意的问题: 1. hash数组记得初始化 2. pOu

Java基础机试题

package day8;import java.util.Scanner;/** * Java基础机试题 * @author:lyrand * */public class convert {        static void exitContinue(){                while (true){            System.out.print("你想继续吗?(y/n)");            Scanner sc = new Scanner(Sys

2015年华为校招机试题和代码实现(分解字符串,拼音转数字,去除重复字符并排序,等式变换)

再来一套2015年的华为机试题. 第一题(60分): 按要求分解字符串,输入两个数M,N:M代表输入的M串字符串,N代表输出的每串字符串的位数,不够补0.例如:输入2,8, "abc" ,"123456789",则输出为"abc00000","12345678","90000000" 分析思路: 容易题 1.获得字符串的长度length后,判断与要输出位数N的大小,大于N的话,直接printf前N位字符,然

九度OJ&amp;北邮机试题(2011网院)

题目一.九度OJ-1177:查找 http://ac.jobdu.com/problem.php?pid=1177 题目描述: 读入一组字符串(待操作的),再读入一个int n记录记下来有几条命令,总共有2中命令:1.翻转  从下标为i的字符开始到i+len-1之间的字符串倒序:2.替换  命中如果第一位为1,用命令的第四位开始到最后的字符串替换原读入的字符串下标 i 到 i+len-1的字符串.每次执行一条命令后新的字符串代替旧的字符串(即下一条命令在作用在得到的新字符串上). 命令格式:第一

考研复试机试题(2009)

Problem A:请写一个程序,给出指定整数范围[a ,b]内所有的完数,一个数如果恰好等于除它本身外的所有因子之和,这个数就称为完数,例如6是完数,因为6=1+2+3. 输入说明:共一组数据,为两个正整数,分别表示a和b(1<a<b<10^5). 输出说明:指定范围内的所有完数,每个数占一行. 输入样本 1 100 输出样本 6 28 解答: /* * 描述: 机试题A解答 * 作者: 张亚超 * 博客: 牟尼的专栏 http://blog.csdn.net/u012027907 *

Java decode机试题

/** *  * java编写encode方法和decode方法,机试题 请你用java,c,c++ * 中任何一种语言实现两个函数encode()和decode(),分别实现对字符串的变换和复原. * 变换函数encode()顺序考察以知字符串的字符,按以下规则逐组生成新字符串: * (1)若已知字符串的当前字符不是大于0的数字字符,则复制该字符与新字符串中: * (2)若以已知字符串的当前字符是一个数字字符,且他之后没有后继字符,则简单地将它复制到新字符串中: * (3)若以已知字符串的当前