c语言基础题

来源:互联网 发布:男学生衬衣知乎 编辑:程序博客网 时间:2024/05/29 03:09

题目 表示大整数
来源医学部计算概论罗英伟班(高级题)描述若一个数太大,人们很难正确读出这个数。例如1亿=100000000,很容易就把8个0数成7个或9个0,从而读错。 
为了避免这种误差,提出一种方法,写数字的时候,每隔一定长度k,加一个逗号。 
例如,按照西方读数的习惯,每隔三位写一个逗号,1亿=100,000,000能很快读出来100million。 
再例如,按照中国读数的习惯,每隔四位写一个逗号,1亿=1,0000,0000能很快读出来1亿。 
现在给你一个数n,以及逗号的间隔长度k,请写出用逗号隔开之后的数。 

关于输入第一行一个数t(t<=10),表示数据组数。 接下来t行,每行两个整数,n和k,用空格隔开。其中n不超过int的表达范围,1<=k<=5。 
关于输出一共t行,每行为一个用逗号隔开之后的数。 
例子输入
例子输出
312345 312345 1-1234 2
提示12,345 
1,2,3,4,5 
-12,34

如果把k映射到10^k,然后利用整数的除法,需要注意一个问题:0的问题

比如123405 2,结果应该是12,34,05而不是12,34,5


还有一种思路是根本不读入整数,而是读入字符串,然后把逗号插进去

代码:

#include<stdio.h>#include<string.h>int main(){int t, i, k, j;char c[12];scanf("%d", &t);for (i = 1; i <= t; i++){scanf("%s %d", &c, &k);int low = 0, high = strlen(c);if (c[0] == '-')printf("%c", c[low++]);for (j = low; j < high; j++){printf("%c", c[j]);if (high - j>1 && (high - 1 - j) % k == 0)printf("%c", ',');}printf("\n");}return 0;}
题目 IBM编码(字符串)
来源医学院计概2015(熊瑞勤)-jmu描述在“2001太空漫游”这部电影中,一艘宇宙飞船飞往木星。长途飞船上除了飞行员,还有三名处在冬眠状态的科学家。飞船是由智能计算机HAL控制。但在飞行过程中,HAL的行为越来越奇怪,甚至开始杀死所有船员,…... 
电影上映后,变得非常流行,有一些讨论,如"HAL"实际上意味着什么。一些人认为它可能是“启发式算法(Heuristic Algorithm)”的缩写。但最流行的解释是:如果将HAL的每一个字母更换成其在ASCII字母表中的继任者,你得到的会是…IBM,也就是每一个字母用其后继字母替代。 
现在,我们也采取同样的编码方式对信息进行表示。 

即对于给定的字符串,把其中从a-y、A-Y的字母用其后继字母替代,把z和Z用a和A替代。只改变字符串中的字母,字符串中的其他字符保持不变。
关于输入第一行是字符串的数目n(n<=10),用gets(s)读取,再用n=atoi(s)获得整数数值 其余n行每行一个可能含空格的字符串,每个字符串长度小于50个字符,用gets(s)方式读取每行字符串
关于输出输出有n行,每行是一个字符串的编码结果
例子输入
4hello how are you?are you ready?yes, I'm ready!OK, let's go!
例子输出
ifmmp ipx bsf zpv?bsf zpv sfbez?zft, J'n sfbez!PL, mfu't hp!
提示避免gets和scanf在使用时的冲突:用n=atoi(s)把字符串s转换为整数,函数atoi()定义在头文件stdlib.h中

代码:

#include<stdio.h>#include<stdlib.h>#include<string.h>int main(){int t, i, j;char c[60];gets(c);t = atoi(c);for (i = 1; i <= t; i++){gets(c);for (j = 0; j < strlen(c); j++){if(c[j]>='a'&&c[j]<'z'||c[j]>='A'&&c[j]<'Z')printf("%c", c[j]+1);else if (c[j] == 'z' || c[j] == 'Z')printf("%c", c[j] -25);else printf("%c", c[j]);}printf("\n");}return 0;}

题目 医院排号
来源医学院计概2015(高良才)-沈熳婷描述北大校医院最近更新了自己的网上排号系统,考虑到病人的病情程度不同,需要优先考虑病情较重的病人,病情相同的情况下需要把先在网上挂号的病人排在前面。现在给出了请求在同一天看病的n个病人网上挂号的顺序,但是校医院一天只能接收k个病人,请输出校医院当天接收的所有病人的看病顺序。 

关于输入第一行:一个整数t,表示数据的组数: 对于每组数据,分别有两行: 第一行:两个整数n 和k (k不一定小于n),表示请求在同一天看病的病人有n个,医院当天只能接受k个病人 第二行:n个整数,第i个整数表示第i个在网上挂号的病人的病情严重程度 
关于输出对每组数据输出两行: 
第一行:一个整数m(m<=k),表示医院当天实际接受的病人的个数 
第二行:一个整数序列,包含m个整数,用空格隔开,最后一个整数之后是一个换行符,表示医院当天看病的安排,第i个整数表示医院当天接收的第i个病人在原先挂号序列当中的序号。 
例子输入
25 32 3 4 7 46 25 10 4 6 9 7
例子输出
34 3 522 5
提示例子输入输出中一共有两组数据,第一组数据表示当天有5个病人在网上挂号,按照挂号时间先后排列,这五个人的病情程度分别是2,7,4,3,4。同时,医院当天只能接收3个病人。对于第一组数据,医院当天只接收了3个病人,分别是第二个,第三个和第五个(之前5个病人按照病情严重程度排列顺序是4,3,5,2,1)。对第二组数据,严重程度最高的是第2个人,其次是第五个。 

建议使用结构类型描述挂号信息。

代码:

#include<stdio.h>int main(){int t, i, n, k, num[1000],j;scanf("%d", &t);for (i = 1; i <= t; i++){scanf("%d%d", &n, &k);for (j = 1; j <= n; j++)scanf("%d", &num[j]);if (k > n)k = n;printf("%d\n", k);while (k--){int ans = 1;for (j = 2; j <= n; j++)if (num[ans] < num[j])ans = j;printf("%d%s", ans, k ? " " : "\n");num[ans] = 0;}}return 0;}

题目 铺地板
来源医学院计概2015(熊瑞勤)-songqiang描述你是一名室内装潢工程队的配料员。你的伙伴们喜欢采用“之”字型(对角线)的顺序方式给方阵型地面铺大理石地砖,图案如下: 

1  2  6  7  15 
3  5  8  14 16 
4  9  13 17 22 
10 12 18 21 23 
11 19 20 24 25 

这里,1-25按方阵的对角线顺序放置。 

学了 C 语言以后,你决定编写一个程序,帮助你的同伴生成这样的图形。

关于输入地砖方阵的大小N(如:一共25块地砖,由于是正方形阵,则N为5)
关于输出1到N*N这些数所构成的“之字形”方阵(二维数组),同一行数之间用一个空格隔开,每N个数为一行,共N行。
例子输入
4
例子输出
1 2 6 73 5 8 134 9 12 1410 11 15 16

直接把第i行第j列的数求出来即可

代码:

#include<stdio.h>int f(int i, int j,int n){if (i + j > n + 1)return n*n+1-f(n + 1 - i, n + 1 - j, n);int s = (i + j - 2)*(i + j - 1) / 2;if ((i + j) % 2)return s+i;return s + j;}int main(){int i,j,n;scanf("%d", &n);for (i = 1; i <= n; i++){for (j = 1; j < n; j++)printf("%d ", f(i, j, n));printf("%d\n", f(i, n, n));}return 0;}
题目 整数删除若干数字后的最小数
来源医学部计算概论描述给定一个正整数,从这个正整数中删除若干个数字,可以得到一个新的整数。一般而言,采用不同的删除方案,可以得到不同的整数。求所有可能的删除方案产生的最小的整数。 
例如: 
1.对于正整数12345,删除3个数字后产生的最小整数为12; 
2.对于正整数543212345,删除5个数字后产生的最小整数为1234; 
3.对于正整数5432102345,删除5个数字后产生的最小整数为2345; 
4.对于正整数137313731373137,删除5个数字后产生的最小整数为1131373137; 
5.对于正整数132304,删除5个数字后产生的最小整数为0。
关于输入输入有1行。其中包含两个数: 第一个数是一个正整数m,表示将要被删除数字的正整数。m的位数小于100。(对于数字123,其位数为3) 第二个数也是一个正整数k,表示要从第一个数中删除几个数字。两者之间用空格间隔开。 且保证输入的k小于m的位数。
关于输出输出有一行。其中只有一个整数,即:删除若干数字后产生的最小整数。
例子输入
137313731373137 5
例子输出
1131373137
提示1.输入的正整数m的位数可能会很长,超出一个整型变量的表示范围。 
2.如果删除若干数字后产生了一个首数字为0的非零整数,则在输出时不能输出这些0字符。例如,对于正整数5432102345,删除5个数字后产生的最小整数为02345,但在输出时只能输出2345。 
3.如果删除若干数字后产生的整数的值等于0,则只需要输出0。

如果不追求效率的话,比较简单的方式是每次删除1个数字,循环k次就直接得到结果。

如果追求效率的话,删除这k个数字不应该独立进行,应该从左往右依次进行。


方案一:k次独立删除1个数字

只需要寻找所有相邻的数字中,第一次出现降低的地方即可。

比如题目中的137313731373137,第一次出现降低的地方就是最前面的1373中的73

必须是严格降低,对于连续的相等的2个数字,直接忽略即可(而且也必须这样)

找到这种组合,删掉左边的数字即可

代码:

#include<stdio.h>#include<string.h>int main(){char c[105];int k, len, d, i;scanf("%s %d", &c, &k);len = strlen(c);while (k--){d = len - 1;for (i = 1; i < len; i++){if (c[i] < c[i - 1]){d = i - 1;break;}}for (i = d; i < len - 1; i++)c[i] = c[i + 1];len--;}i = 0;while (c[i] == '0'&&i<len)i++;if (i == len)printf("0");else while (i < len)printf("%c", c[i++]);return 0;}
方案二:从左往右依次删除k个数字

从左往右扫描的时候需要注意的是,删掉1个数字之和,指针不仅不能前进,而且还需要回溯。

比如对于相邻的3位abc,发现b>c然后删掉b之和,下一步应该是比较a和c的大小

但是这个比较的工作必须由循环的下一次执行来完成,否则就无穷无尽了。

所以这里只需要i-=2即可。

同时,如果最开始就删掉bc中的b,而b就是最左边的数字,这个时候就不能再比较ac了,因为根本没有ac,强行比较会数组溢出。这种情况只需要continue即可,当然,也可以像下面这样做。

整体代码和方案一里面的差不多

代码:

#include<string.h>int main(){char c[105];int k, len, d, i, j;scanf("%s %d", &c, &k);len = strlen(c);for (i = 1; i < len && k>0; i++){if (i && c[i] < c[i - 1]){for (j = i; j < len; j++)c[j - 1] = c[j];i-=2, len--, k--;}}len -= k;i = 0;while (c[i] == '0'&&i<len)i++;if (i == len)printf("0");else while (i < len)printf("%c", c[i++]);return 0;}

0 0
原创粉丝点击