文章目录
1002 写出这个数
分数 20
作者 CHEN, Yue
单位 浙江大学
读入一个正整数 n,计算其各位数字之和,用汉语拼音写出和的每一位数字。
输入格式:
每个测试输入包含 1 个测试用例,即给出自然数 n 的值。这里保证 n 小于 10
100
。
输出格式:
在一行内输出 n 的各位数字之和的每一位,拼音数字间有 1 空格,但一行中最后一个拼音数字后没有空格。
输入样例:
1234567890987654321123456789
输出样例:
yi san wu
**思考:**题目不难,我的问题在于用整形存储数时,当太大时,存储不了,所以可以用数组存储再计算
#include<stdlib.h>
#include<stdio.h>
#define LEN 1000
int main(){
char n[LEN];
int len=0,sum=0;
for(int i=0;i<LEN;i++){
scanf("%c",&n[i]);
if(n[i]=='\n'){
len=i;
break;
}
}
//求和
for(int i=0;i<len;i++){
switch(n[i]){
case '0': sum+=0;break;
case '1': sum+=1;break;
case '2': sum+=2;break;
case '3': sum+=3;break;
case '4': sum+=4;break;
case '5': sum+=5;break;
case '6': sum+=6;break;
case '7': sum+=7;break;
case '8': sum+=8;break;
case '9': sum+=9;break;
}
}
//得到和的每一位
int c[LEN],d[LEN],ll=0,jj=1;
for(int i=0;i<LEN;i++){
c[i]=sum/jj%10;
d[i]=sum/(jj*10);
jj*=10;
if(d[i]==0){
ll=i;
break;
}
}
for(int i=ll;i>=0;i--){
switch(c[i]){
case 0: printf("ling");break;
case 1: printf("yi");break;
case 2: printf("er");break;
case 3: printf("san");break;
case 4: printf("si");break;
case 5: printf("wu");break;
case 6: printf("liu");break;
case 7: printf("qi");break;
case 8: printf("ba");break;
case 9: printf("jiu");break;
}
if(i!=0)printf(" ");
}
}
1004 成绩排名
分数 20
作者 CHEN, Yue
单位 浙江大学
读入 n(>0)名学生的姓名、学号、成绩,分别输出成绩最高和成绩最低学生的姓名和学号。
输入格式:
每个测试输入包含 1 个测试用例,格式为
第 1 行:正整数 n
第 2 行:第 1 个学生的姓名 学号 成绩
第 3 行:第 2 个学生的姓名 学号 成绩
… … …
第 n+1 行:第 n 个学生的姓名 学号 成绩
其中姓名和学号均为不超过 10 个字符的字符串,成绩为 0 到 100 之间的一个整数,这里保证在一组测试用例中没有两个学生的成绩是相同的。
输出格式:
对每个测试用例输出 2 行,第 1 行是成绩最高学生的姓名和学号,第 2 行是成绩最低学生的姓名和学号,字符串间有 1 空格。
输入样例:
3
Joe Math990112 89
Mike CS991301 100
Mary EE990830 95
输出样例:
Mike CS991301
Joe Math990112
思考:题目不难,但是运行程序时总是结果不对,原因是数组长度没有留够,任何字符串末尾都会自动加上’\0’,'\0’是占一个位置的,所以如果一个长度为10的字符串要放在一个字符串数组里面的话,这个字符串数组长度至少为11。
tips:字符串知识
https://blog.csdn.net/huhuhuhuhuhuha/article/details/124604724
#include<stdlib.h>
#include<stdio.h>
struct student{
char name[20];
char num[20];
int score;
};
int main(){
int n;
scanf("%d",&n);
getchar();
struct student stu[1000];
// input
for(int i=0;i<n;i++){
scanf("%s %s %d",stu[i].name,stu[i].num,&stu[i].score);
getchar();
}
// judge
int max=0,min=0;//成绩最高和最低的学生所在下标
for(int i=1;i<n;i++){
if(stu[i].score>stu[max].score){
max=i;
}
if(stu[i].score<stu[min].score){
min=i;
}
}
printf("%s %s\n",stu[max].name,stu[max].num);
printf("%s %s\n",stu[min].name,stu[min].num);
}
1005 继续(3n+1)猜想
分数 25
作者 CHEN, Yue
单位 浙江大学
卡拉兹(Callatz)猜想已经在1001中给出了描述。在这个题目里,情况稍微有些复杂。
当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中遇到的每一个数。例如对 n=3 进行验证的时候,我们需要计算 3、5、8、4、2、1,则当我们对 n=5、8、4、2 进行验证的时候,就可以直接判定卡拉兹猜想的真伪,而不需要重复计算,因为这 4 个数已经在验证3的时候遇到过了,我们称 5、8、4、2 是被 3“覆盖”的数。我们称一个数列中的某个数 n 为“关键数”,如果 n 不能被数列中的其他数字所覆盖。
现在给定一系列待验证的数字,我们只需要验证其中的几个关键数,就可以不必再重复验证余下的数字。你的任务就是找出这些关键数字,并按从大到小的顺序输出它们。
输入格式:
每个测试输入包含 1 个测试用例,第 1 行给出一个正整数 K (<100),第 2 行给出 K 个互不相同的待验证的正整数 n (1<n≤100)的值,数字间用空格隔开。
输出格式:
每个测试用例的输出占一行,按从大到小的顺序输出关键数字。数字间用 1 个空格隔开,但一行中最后一个数字后没有空格。
输入样例:
6
3 5 6 7 8 11
输出样例:
7 6
思考:本题重点在于思路,num[LEN]存储输入的数字,cpnum[LEN],输入数字的拷贝,status[LEN]判断是否为关键数,初始为1,a[LEN]存储验证过程中的数。
对num数组进行for循环,循环后会得到一串a[]验证过程中的数,把cpnum中的每个数都和a中的数比较,如果相等,就把status对应位置的值赋值为0,表明这个数被覆盖了。
for循环完后,status中的值全部更新完毕,拿到status中值为1对应的下标i,把cpnum[i]存到新数组prit中,再排序输出prit中的值。
#include<stdlib.h>
#include<stdio.h>
#define LEN 2000
struct number{
int n;//存放输入的那个数字
int a[100];//存放 验证过程中的数字
int len;//a数组的长度
};
int main(){
int k;
scanf("%d",&k);
getchar();
int num[LEN],cpnum[LEN],status[LEN],a[LEN]; //存输入;存输入的拷贝;表示是否是关键字,1为是;存验证过程中的数
//input
for(int i=0;i<k;i++){
scanf("%d",&num[i]);
cpnum[i]=num[i];
status[i]=1;
}
for(int i=0;i<k;i++){
int t=0,len=0;
for(int ai=0;ai<LEN;ai++)a[ai]=0;
if(status[i]==1){
while(num[i]!=1){
if(num[i]%2==0){
num[i]/=2;
a[t++]=num[i];
}else{
num[i]=(3*num[i]+1)/2;
a[t++]=num[i];
}
}
len=t;
//判断状态,不是关键数status为0
for(int j=0;j<k;j++){
for(int m=0;m<len;m++){
if(a[m]==cpnum[j]){
status[j]=0;
}
}
}
}
}
int chang=0,prit[LEN];
for(int i=k-1;i>=0;i--){
if(status[i]==1){
prit[chang++]=cpnum[i];
}
}
//排序
for(int i=0;i<chang-1;i++){
for(int j=i+1;j<chang;j++){
if(prit[j]>prit[i]){
int temp;
temp=prit[i];
prit[i]=prit[j];
prit[j]=prit[i];
}
}
}
//输出
for(int i=0;i<chang;i++){
if(i==chang-1)printf("%d",prit[i]);
else printf("%d ",prit[i]);
}
}
1007 素数对猜想
输入格式:
输入在一行给出正整数N。
输出格式:
在一行中输出不超过N的满足猜想的素数对的个数。
输入样例:
20
输出样例:
4
思考:题目不难,主要思路是拿到小于n是素数数组,然后用for循环,判断相邻2个数差是否为2;提交代码后,有一个测试点过不了,提示段错误
检查之后发现把数字的大小设置小了,改大之后就好了,谨记:要根据题目条件给出的数字大小来设定数组大小,防止越界或溢出
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#define LEN 100000
int issu(long int n){
int is=1;
if(n==2)return 1;
else{
int t=sqrt(n);
for(long int i=2;i<=t;i++){
if(n%i==0){
is=0;
break;
}
}
return is;
}
}
int main(){
long int n;
scanf("%ld",&n);
// 2 3 5 7 11 13 17 19
long int index=0,a[LEN];
for(long int i=2;i<=n;i++){
if(issu(i)==1){
a[index++]=i;
}
}
// for(int i=0;i<index;i++)printf("%d ",a[i]);
long int count=0;//满足猜想的对数
for(long int i=0;i<index-1;i++){
if(a[i+1]-a[i]==2)count++;
}
printf("%ld",count);
}
1009 说反话
分数 20
作者 CHEN, Yue
单位 浙江大学
给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。
输入格式:
测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用 1 个空格分开,输入保证句子末尾没有多余的空格。
输出格式:
每个测试用例的输出占一行,输出倒序后的句子。
输入样例:
Hello World Here I Come
输出样例:
Come I Here World Hello
思考:本体重点在于处理连续多个空格;
#include<stdlib.h>
#include<stdio.h>
struct word {
char c[100];
int len;
};
int main() {
struct word words[100];
int wordlen = 0;//表示一共有多少个单词
int flag = 0;//表示前一个字符是否为空格,0表示不是空格
char temp;//表示当前读入的字符
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 100; j++) {
while (1) {
temp = getchar();
if (temp == ' ' && flag == 1) {//当前字符为空格且前一个字符也是空格,说明是多个空格连续的情况,继续循环
flag = 1;
}
else if (temp != ' ') {//当前字符不为空格,把flag更新,跳出循环
flag = 0;
break;
}
else if (temp == '\n') {//当前是换行,说明全部输入结束跳出while
break;
}
else if (temp == ' ' && flag == 0) {//当前是空格且前一个不是空格,说明一个单词结束了,跳出while循环
words[i].len = j;//得到一个单词的长度
break;
}
}
if (temp == ' ' && flag == 0) {//当前是空格且前一个不是空格,说明一个单词结束了,跳出一个for循环,为什么和27行代码一样的原因是,跳出while循环不能更新i,也就无法输入新单词,所以for循环也要跳出来
break;
}
if (temp == '\n') {//当前是换行,说明全部输入结束跳出for循环,且可以得到单词的个数,就是i的值
words[i].len = j;
wordlen = i;
break;
}
words[i].c[j] = temp;
}
if (wordlen != 0)break;//如果不判断wordlen的值,就无法跳出最外层for循环,就一直在输出状态
}
for (int i = wordlen; i >= 0; i--) {
for (int j = 0; j < words[i].len; j++) {
printf("%c", words[i].c[j]);
}
if (i != 0)printf(" ");
}
}
1010 一元多项式求导
分数 25
作者 DS课程组
单位 浙江大学
设计函数求一元多项式的导数。(注:x
n
(n为整数)的一阶导数为nx
n−1
。)
输入格式:
以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过 1000 的整数)。数字间以空格分隔。
输出格式:
以与输入相同的格式输出导数多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。注意“零多项式”的指数和系数都是 0,但是表示为 0 0。
输入样例:
3 4 -5 2 6 1 -2 0
输出样例:
12 3 -10 1 6 0
思考:这道题输入我一直都有问题,scanf(“%d %d”,&xs[xsi],&zs[zsi])!=EOF这句话pta上可以正常运行,在dev上就不能正常运行,而是一直卡在循环。同时我的解法不完善。等有空了再思考一下
tips:附上EOF相关知识
:链接
#include<stdlib.h>
#include<stdio.h>
#define LEN 10000
int main() {
int xs[LEN], zs[LEN], len = 0;
char c;
int temp[LEN];
int xsi = 0, zsi = 0;
while (scanf("%d %d", &xs[xsi], &zs[zsi]) != EOF) {
xsi++;
zsi++;
}
for (int i = 0; i < xsi; i++) {
if (zs[i] == 0) {
xs[i] = 0;
}
else {
xs[i] = xs[i] * zs[i];
zs[i]--;
}
}
for (int i = 0; i < xsi; i++) {
printf("%d ", xs[i]);
if (i == xsi - 1)printf("%d", zs[i]);
else printf("%d ", zs[i]);
}
}
1011 A+B 和 C
分数 15
作者 HOU, Qiming
单位 浙江大学
输入格式:
输入第 1 行给出正整数 T (≤10),是测试用例的个数。随后给出 T 组测试用例,每组占一行,顺序给出 A、B 和 C。整数间以空格分隔。
输出格式:
//输入样例:
4
1 2 3
2 3 4
2147483647 0 2147483646
0 -2147483648 -2147483647
//输出样例:
Case #1: false
Case #2: true
Case #3: true
Case #4: false
思考:题目不难,主要是输入要注意,因为题目给定的整数区间比较大,因此普通的int型不满足要求,要用long long int定义整数变量,在输入时要注意用%lld输入
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
struct num{
long long int a;
long long int b;
long long int c;
int count;
};
int main(){
struct num nums[10];
int t;
scanf("%d",&t);
for(int i=0;i<t;i++){
scanf("%lld %lld %lld",&nums[i].a,&nums[i].b,&nums[i].c);
nums[i].count=i+1;
}
for(int i=0;i<t;i++){
if(nums[i].a+nums[i].b>nums[i].c)printf("Case #%d: true\n",nums[i].count);
else printf("Case #%d: false\n",nums[i].count);
}
}
1017 A除以B
分数 20
作者 CHEN, Yue
单位 浙江大学
本题要求计算 A/B,其中 A 是不超过 1000 位的正整数,B 是 1 位正整数。你需要输出商数 Q 和余数 R,使得 A=B×Q+R 成立。
输入格式:
输入在一行中依次给出 A 和 B,中间以 1 空格分隔。
输出格式:
在一行中依次输出 Q 和 R,中间以 1 空格分隔。
输入样例:
123456789050987654321 7
输出样例:
17636684150141093474 3
思考:本题涉及高精度的除法,相关信息如下链接,我自己的做法没有全部AC,有空再改
tips:高精度运算
#include<stdlib.h>
#include<stdio.h>
int main() {
char a[1001];
int b, r;
scanf("%s %d", a, &b);
int q[1001], len = 0;
for (int i = 0; i < 1001; i++) {
if (a[i] == '\0') {
len = i;
break;
}
}
int temp = 0, trans = 0;
int j = 0;//结果数组的下标
for (int i = 0; i < len; i++) { //101 5 =20..1
trans = a[i] - '0';
q[j++] = (temp * 10 + trans) / b;
temp = (temp * 10 + trans) % b;
}
for (int i = 0; i < j; i++) {
if (i == 0 && q[0] == 0) {
}
else {
printf("%d", q[i]);
}
}
printf(" %d", temp);
}
1020 月饼
分数 25
作者 CHEN, Yue
单位 浙江大学
月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼。现给定所有种类月饼的库存量、总售价、以及市场的最大需求量,请你计算可以获得的最大收益是多少。
注意:销售时允许取出一部分库存。样例给出的情形是这样的:假如我们有 3 种月饼,其库存量分别为 18、15、10 万吨,总售价分别为 75、72、45 亿元。如果市场的最大需求量只有 20 万吨,那么我们最大收益策略应该是卖出全部 15 万吨第 2 种月饼、以及 5 万吨第 3 种月饼,获得 72 + 45/2 = 94.5(亿元)。
输入格式:
每个输入包含一个测试用例。每个测试用例先给出一个不超过 1000 的正整数 N 表示月饼的种类数、以及不超过 500(以万吨为单位)的正整数 D 表示市场最大需求量。随后一行给出 N 个正数表示每种月饼的库存量(以万吨为单位);最后一行给出 N 个正数表示每种月饼的总售价(以亿元为单位)。数字间以空格分隔。
输出格式:
对每组测试用例,在一行中输出最大收益,以亿元为单位并精确到小数点后 2 位。
输入样例:
3 20
18 15 10
75 72 45
输出样例:
94.50
思考:第一次提交不能完全AC,网上看别人的教程才知道自己有2个测试点没考虑到
1、输入的每种月饼的库存量和总售价,只是正数,而不是正整数,即可能含有小数部分。变量应该定义为float型,而不是int型。
2、有可能市场需求量大于所有种类月饼的库存量之和
考虑之后就能AC了
#include<stdlib.h>
#include<stdio.h>
//4.16 4.8 4.5
struct yue {
float sto;//库存
float total;//总价
float perprice;
int tagg;//表示是否被访问过
};
int main() {
int n, d, sto[1001], price[1001];//n种类数,d最大需求量
float sum = 0;
scanf("%d %d", &n, &d);
int copyd = d;
struct yue bing[1001];
float zongliang = 0, zongjia = 0;
for (int i = 0; i < n; i++) {
scanf("%f", &bing[i].sto);
zongliang += bing[i].sto;
}
for (int i = 0; i < n; i++) {
scanf("%f", &bing[i].total);
bing[i].tagg = 0;
zongjia += bing[i].total;
}
if (zongliang <= d)printf("%.2f", zongjia);
else {
float perprice[1001];
for (int i = 0; i < n; i++) {
bing[i].perprice = bing[i].total * 1.0 / bing[i].sto;
}
float maxprice;//记录当前最大单价
int maxindex[1001], maxi = 0;//存放当前最大单价下标
int j = 0, len = 0;
while (1) {
maxprice = -1;
for (int i = 0; i < n; i++) {
if (bing[i].perprice >= maxprice && bing[i].tagg == 0) {
maxprice = bing[i].perprice;
maxi = i;
}
}
maxindex[j++] = maxi;
bing[maxi].tagg = 1;
len++;
if (bing[maxi].sto >= d) {
break;
}
else {
sum += bing[maxi].total;
d -= bing[maxi].sto;
}
}
sum += d * bing[maxi].perprice;
printf("%.2f", sum);
}
}
1022 D进制的A+B
输入格式:
输入在一行中依次给出 3 个整数 A、B 和 D。
输出格式:
输出 A+B 的 D 进制数。
输入样例:
123 456 8
输出样例:
1103
思路:借助10进制转换成2进制的思路,除2取余法,要注意和为0的情况,输出的时候要颠倒过来输出
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<math.h>
#define LEN 100;
main(){
int a,b,d;
scanf("%d %d %d",&a,&b,&d);
int sum=a+b;
int temp;
int res[1000],t=0;
if(sum==0){
printf("0");
}else{
while(sum!=0){
temp=sum%d;
res[t++]=temp;
sum/=d;
}
for(int i=t-1;i>=0;i--){
printf("%d",res[i]);
}
}
}
1026 程序运行时间
思路:思路简单,先把小时算出来,再算分,再算秒,需要注意的地方一个是四舍五入,一个是时分秒都要是整数,注意不要用小数除
tips:四舍五入的方法
https://blog.csdn.net/m0_72482689/article/details/125997219
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<math.h>
int main(){
double c1,c2;
long long int CLK_TCK =100;
scanf("%lf %lf",&c1,&c2);
double cha;
cha=(c2-c1)*1.0/CLK_TCK;
cha=round(cha);
int h,m,s;
h=cha/3600;
m=(cha-h*3600)/60;
s=cha-h*3600-60*m;
printf("%02d:%02d:%02d",h,m,s);
}