水题总结NYOJ74,1094,60,975,111,833

本文总结了编程题目中遇到的问题,强调了题目要求的重要性,特别是字符串输入输出的注意事项,如scanf与gets的区别,以及printf和puts的使用。作者分享了在处理小学生算术、奖学金问题、521问题等题目时的经验,提醒读者在循环和变量使用上的良好习惯。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


做题中暴露的问题还是有很多:

1.题目中输入中的要求是最应该要注意的,有时候从要求和范围可以判断出题目的正确做法。

2.字符串的输入问题还是有很多不足,在做题的时候会出现很多不太清楚的地方,如下文的奖学金例子,当时的空格问题让我懵了很久

在这里顺便就字符串的输入输出应注意的点做个总结,可能有些不足,以后会随时补充

scanf("%s",a),最应注意的就运到空格回车输入就终止

需要强调一点,scanf("%s",str)在遇到'\n'(回车)或' '(空格)时输入结束,但'\n'(回车)或' '(空格)停留在出入缓冲区,如处理不慎会影响下面的输入;而gets()对enter较为敏感,gets(str)遇到'\n'(回车)时输入结束,但'\n'(回车)已被替换为'\0',存储于字符串中,输入缓冲中没有遗留的'\n'(回车),不会影响后续的输入。这也是经常scanf->getchar->gets的原因

printf(“%s”,a)却是可以输出空格的,输出的话puts还具有自动换行的功能

3.当循环需要用到一个变量来做标记时,千万要记得在循环头将其归0;这是一个需要拥有的好习惯,还有内外循环时外变量和内变量同时用到时更应该注意,具体看521超时的那篇,有标记,都是血和泪的教训,虽然说wp几次后能够发现问题,但会浪费相当多的时间

小学生算术

时间限制: 3000 ms  |  内存限制: 65535 KB
难度: 1
描述
很多小学生在学习加法时,发现“进位”特别容易出错。你的任务是计算两个三位数在相加时需要多少次进位。你编制的程序应当可以连续处理多组数据,直到读到两个0(这是输入结束标记)。
输入
输入两个正整数m,n.(m,n,都是三位数)
输出
输出m,n,相加时需要进位多少次。
样例输入
123 456
555 555
123 594
0 0
样例输出
0
3 

1

这道题并不是一道很难的题,纠结了我好久的原因是因为我想字符串转化为数字去作,让我感到很奇怪的就是为什么a[0]相减永远都是错的而其余的数都是对的,我百度了好久也没找出什么

#include<stdio.h>//NYOJ74错误版本
int main(void)
{
	int flag,i,sum,m,n;
	char a[3];char b[3];
	while(1)
	{
		scanf("%s %s ",a,b);
		if(a[0]=='0'&&b[0]=='0')
			break;
		sum=0;flag=0;
		for(i=0;i<=2;i++)
		{
			m=a[i]-'0';
			n=b[i]-'0';
			if(flag==1)
				m++;
			if(m+n>9)
			{
				sum++;
				flag=1;
			}
			else
			{
				flag=0;
			}
		}
		printf("%d\n",sum);
	}
}
#include <stdio.h> //NYOJ74正确版本
#include <string.h>  
int main()  
{  
    int a,b;  
    int a1,a2,a3,b1,b2,b3;  
    while(scanf("%d%d",&a,&b)&&(a||b))  
    {  
    	if(b>999&&a<100&&b>999&&b<100)
    		continue;
        int cnt=0;  
        a1=a/100;  
        a2=a/10%10;  
        a3=a%10;  
        b1=b/100;  
        b2=b/10%10;  
        b3=b%10;  
        if(a3+b3>=10)  
        {  
            cnt++;  
            a2++;  
        }  
        if(a2+b2>=10)  
        {  
            cnt++;  
            a1++;  
        }  
        if(a1+b1>=10)  
        {  
            cnt++;  
        }  
        printf("%d\n",cnt);  
    }  
    return 0;  
} 

数字分隔(二)

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 3
描述

在一个遥远的国家,银行为了更快更好的处理用户的订单,决定将一整串的数字按照一定的规则分隔开来,分隔规则如下:

1、实数的整数部分按照每三个数字用逗号分隔开(整数部分的高位有多余的0时,需先将多余的0过滤后,再进行数字分隔,如:0001234567 输出结果为1,234,567.00)

2、小数部分保留两位小数(四舍五入)

3、如果该数是负的,则在输出时需用括号将分隔后的数字括起来,例如:-10005.1645的输出结果为(10,005.16)  

输入
多组测试数据(以eof结尾),每行输入一个实数n(n的位数小于100)
输出
输出分隔后的结果
样例输入
00012345670.0000-10005.1645

样例输出

1,234,567.000.00(10,005.16)

#include<stdio.h>NYOJ1094数的分割(二) //无脑版本
int main(void)
{
	int i,j,s,flag,p,a[101];
	double n,h,k,l;
	while(scanf("%lf",&n)!=EOF)
	{
		for(i=1;i<101;i++)
		{
			a[i]=0;
		}
		l=0;
		if(n<0)
		{
			printf("(");
			l=n;
			n*=-1;
		}
			
		h=n;
		s=(int) n;
		k=h-s;
		i=1;
		while(s)
		{
			a[i++]=s%10;
			s/=10;
		}
		flag=0;
		p=(i-1)%3;
		{
			if(p>0)
			{
				for(j=i-1;j>=i-p;j--)
				{
					printf("%d",a[j]);
				}
				printf(",");
			}
		}
		for(j=i-1-p;j>=2;j--)
		{
			flag++;
			printf("%d",a[j]);
			if(flag==3&&j!=2)
			{
				printf(",");
				flag=0; 
			}
		}
		printf("%.2lf",k+a[1]);
		if(l<0)
		{
			printf(")");
		}
		printf("\n");
	}
} 
把这道题放进来主要是提醒自己不能为了刷题而刷题,题目中已经明显提到了n的位数为100位,还想到用取余就真的有点水了

谁获得了最高奖学金

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 2
描述
    某校的惯例是在每学期的期末考试之后发放奖学金。发放的奖学金共有五种,获取的条件各自不同:
  1) 院士奖学金,每人8000元,期末平均成绩高于80分(>80),并且在本学期内发表1篇或1篇以上论文的学生均可获得;
  2) 五四奖学金,每人4000元,期末平均成绩高于85分(>85),并且班级评议成绩高于80分(>80)的学生均可获得;
  3) 成绩优秀奖,每人2000元,期末平均成绩高于90分(>90)的学生均可获得;
  4) 西部奖学金,每人1000元,期末平均成绩高于85分(>85)的西部省份学生均可获得;
  5) 班级贡献奖,每人850元,班级评议成绩高于80分(>80)的学生干部均可获得;
  只要符合条件就可以得奖,每项奖学金的获奖人数没有限制,每名学生也可以同时获得多项奖学金。例如姚林的期末平均成绩是87分,班级评议成绩82分,同时他还是一位学生干部,那么他可以同时获得五四奖学金和班级贡献奖,奖金总数是4850元。
  现在给出若干学生的相关数据,请计算哪些同学获得的奖金总数最高(假设总有同学能满足获得奖学金的条件)。
输入
第一行输入数据N,表示测试数据组数(0<N<100),每组测试数据输入的第一行是一个整数X(1 <= X <= 100),表示学生的总数。接下来的X行每行是一位学生的数据,从左向右依次是姓名,期末平均成绩,班级评议成绩,是否是学生干部,是否是西部省份学生,以及发表的论文数。姓名是由大小写英文字母组成的长度不超过20的字符串(不含空格);期末平均成绩和班级评议成绩都是0到100之间的整数(包括0和100);是否是学生干部和是否是西部省份学生分别用一个字符表示,Y表示是,N表示不是;发表的论文数是0到10的整数(包括0和10)。每两个相邻数据项之间用一个空格分隔。
输出
  每组测试数据输出包括三行,第一行是获得最多奖金的学生的姓名,第二行是这名学生获得的奖金总数。如果有两位或两位以上的学生获得的奖金最多,输出他们之中在输入文件中出现最早的学生的姓名。第三行是这X个学生获得的奖学金的总数。
样例输入
1
4
YaoLin 87 82 Y N 0
ChenRuiyi 88 78 N Y 1
LiXin 92 88 N N 0
ZhangQin 83 87 Y N 1
样例输出
ChenRuiyi
9000
28700

#include<stdio.h>///NYOJ60谁获得了最高奖学金 
struct student
{
	char a[20];
	int b,c,f,money;
	char d,e;
};
int main(void)
{
	int x,n,i,j,max,sum;
	scanf("%d",&x);
	if(0<x&&x<100)
	while(x--)
	{
	scanf("%d",&n);
	if(n<1&&n>100)
		continue;
	struct student m[n];
	for(i=0;i<n;i++)
	{///输入时空格很重要 
		scanf("%s %d %d %c %c %d",m[i].a,&m[i].b,&m[i].c,&m[i].d,&m[i].e,&m[i].f);
		m[i].money=0;
	}
	sum=0;
	for(i=0;i<n;i++)
	{
		if(m[i].b>80&&m[i].f>=1)
		{
			m[i].money+=8000;
		}
		if(m[i].b>85&&m[i].c>80)
		{
			m[i].money+=4000;
		}
		if(m[i].b>90)
		{
			m[i].money+=2000;
		}
		if(m[i].b>85&&m[i].e=='Y')
		{
			m[i].money+=1000;
		}
		if(m[i].c>80&&m[i].d=='Y')
		{
			m[i].money+=850;
		}
		sum+=m[i].money;
	}
	int t=1;max=0;
	for(i=0;i<n;i++)
	{
		if(m[i].money>t)
		{
			t=m[i].money;
			max=i;
		}
	}
	printf("%s\n%d\n%d\n",m[max].a,m[max].money,sum);
	} 
}

关于521

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 2
描述

Acm队的流年对数学的研究不是很透彻,但是固执的他还是想一头扎进去。

浏览网页的流年忽然看到了网上有人用玫瑰花瓣拼成了521三个数字,顿时觉得好浪漫,因为每个男生都会不经意的成为浪漫的制造者。此后,流年走到哪里都能看到521三个数字,他怒了,现在他想知道在连续的数中有多少数全部包含了这三个数字。例如12356就算一个,而5111就不算。特别的,如果他看到了521三个数连续出现,会特别的愤怒。例如35210

输入
多组测试数据:
一行给定两个数a,b(0<a,b<1000000),表示数字的开始和结束。
输出
一行显示他想要知道的数有几个及显示有多少个数字令他特别的愤怒。用空格隔开。
样例输入
200 500
300 900
1 600
样例输出
Case 1:2 0
Case 2:2 1
Case 3:6 1

相当打击的一道题目,写出来然后给超时了,查了一下别人家的代码才发现了自己的代码写的很没有水准,还有以后关键的变量名需要写的自己能够看的懂

#include<stdio.h>//自己写的,超时了
int main(void)
{
	int a,b,i,j,sum,s,book[10],t[10],yu,sum1,k,jishu=0;
	while(scanf("%d%d",&a,&b))
	{ 
	jishu++;
		sum=0;sum1=0;
	if(a>0&&b<1000000&&a<b)
	for(i=a;i<=b;i++)
	{
		s=0;
		for(j=1;j<10;j++)
		{
			book[j]=0;
			t[j]=0;
		}
		j=i;/继续用while(i)的话就哭死了、、两个循环时变量相同时要吃大亏//
		while(j)
		{
			yu=j%10;
			if(yu==1||yu==2||yu==5)
			{
				if(book[yu]==0)
				{
					book[yu]++;
					t[s++]=yu;
				}
			}
			j/=10;
		}
		if(book[1]&&book[2]&&book[5])
			sum++;
		for(k=0;k<s-2;k++)
		{
			if(t[k]==1&&t[k+1]==2&&t[k+2]==5)
				sum1++;
		}
	} 
	printf("Case %d:%d %d\n",jishu,sum,sum1);
}
}
#include<stdio.h> //别人家代码
struct dmxy
{
int x;//普通愤怒 
int y;//特别愤怒 
}a[1000005];
int main()
{
int i,j,k=0;a[125].x=1,a[521].y=1; //普通愤怒最早从125开始,特别愤怒最早从521开始
for(i=0; i<1000001; i++)//从头到尾遍历一遍
{
int c[3]={0};
if(i%10==5||i%100/10==5||i%1000/100==5||i%10000/1000==5||i%100000/10000==5||i%1000000/100000==5)//以下都是判断是否有1 2 5 三个数字
c[2]=1;
if(i%10==2||i%100/10==2||i%1000/100==2||i%10000/1000==2||i%100000/10000==2||i%1000000/100000==2)//这些取余也是值得一看
c[1]=1;
if(i%10==1||i%100/10==1||i%1000/100==1||i%10000/1000==1||i%100000/10000==1||i%1000000/100000==1)
c[0]=1;
if(c[0]&&c[1]&&c[2]) a[i].x=a[i-1].x+1;
else a[i].x=a[i-1].x;
if(i%1000==521||i%10000/10==521||i%100000/100==521||i%1000000/1000==521) a[i].y=a[i-1].y+1;
else a[i].y=a[i-1].y;
}
while(scanf("%d %d",&i,&j))
{int m;
k++;
printf("Case %d:%d %d\n",k,a[j].x,a[j].y);
}
return 0;
}

分数加减法

时间限制: 3000 ms  |  内存限制: 65535 KB
难度: 2
描述
编写一个C程序,实现两个分数的加减法
输入
输入包含多行数据 
每行数据是一个字符串,格式是"a/boc/d"。 
其中a, b, c, d是一个0-9的整数。o是运算符"+"或者"-"。 

数据以EOF结束 
输入数据保证合法
输出
对于输入数据的每一行输出两个分数的运算结果。 
注意结果应符合书写习惯,没有多余的符号、分子、分母,并且化简至最简分数
样例输入
1/8+3/8
1/4-1/2
1/3-1/3
样例输出
1/2
-1/4
0


#include<stdio.h>  
char str[20];  
int Gcd(int m,int n)  
{  
    if (m==0) return n;  
    return Gcd(n%m,m);  
}  
int main()  
{  
    int fz,fm,gcd;  
    while(scanf("%s",str)!=EOF)  
    {  
        if(str[3]=='-')   
            fz=(str[0]-'0')*(str[6]-'0')-(str[2]-'0')*(str[4]-'0'); 
        else   
            fz=(str[0]-'0')*(str[6]-'0')+(str[2]-'0')*(str[4]-'0');  
        if(fz)  
        {  
            fm=(str[2]-'0')*(str[6]-'0');  
            gcd=Gcd(fz,fm);  
            if(gcd<0) gcd=-gcd;  
            if(fm/gcd==1) printf("%d\n",fz/gcd);  
            else printf("%d/%d\n",fz/gcd,fm/gcd);  
        }  
        else puts("0");  
    }  
}  

字符串替换

时间限制: 3000 ms  |            内存限制: 65535 KB
难度: 2
描写叙述
编写一个程序实现将字符串中的全部"you"替换成"we"
输入
输入包括多行数据 

每行数据是一个字符串,长度不超过1000 
数据以EOF结束
输出
对于输入的每一行。输出替换后的字符串
例子输入
you are what you do
例子输出
we are what we do

#include<stdio.h>
char str[1002];
int main()
{
  int i,n;
  while(scanf("%d",&n)!=EOF)//没有它就是错的...
  {
  	gets(str);
    i=0;
    while(str[i]!='\0')
    if(str[i]=='y'&&str[i+1]=='o'&&str[i+2]=='u')
    {
      printf("we");
      i+=3;
    }
    else
     { 
        printf("%c",str[i]);
        i++;
     }
    putchar('\n');
  }
  return 0;
}        

取石子(七)

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 1
描述

Yougth和Hrdv玩一个游戏,拿出n个石子摆成一圈,Yougth和Hrdv分别从其中取石子,谁先取完者胜,每次可以从中取一个或者相邻两个,Hrdv先取,输出胜利着的名字。

输入
输入包括多组测试数据。
每组测试数据一个n,数据保证int范围内。
输出
输出胜利者的名字。
样例输入
2
3
样例输出
Hrdv
Yougth


代码及其简单,但思想才是这道题的精华,可以把所有的数都连成圆圈,当第一次取完后,接下来的人只要在继续将圆分成两条链即可(千万不要忽视相邻这个条件),然后你会发现,怎么都是第二个胜利

#include<stdio.h>
int main(void)
{
	int n,i,j;
	while(scanf("%d",&n)!=EOF)
	{
		if(n==1||n==2)
		{
			printf("Hrdv\n");
			continue;
		}
		else
		{
			printf("Yougth\n");
		}
	}
	return 0;
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值