1、h0094. 乒乓球
题目描述:
国际乒联现在主席沙拉拉自从上任以来就立志于推行一系列改革,以推动乒乓球运动在全球的普及。
其中11分制改革引起了很大的争议,有一部分球员因为无法适应新规则只能选择退役。
华华就是其中一位,他退役之后走上了乒乓球研究工作,意图弄明白11分制和21分制对选手的不同影响。
在开展他的研究之前,他首先需要对他多年比赛的统计数据进行一些分析,所以需要你的帮忙。
华华通过以下方式进行分析,首先将比赛每个球的胜负列成一张表,然后分别计算在11分制和21分制下,双方的比赛结果(截至记录末尾)。
比如现在有这么一份记录,(其中W表示华华获得一分,L表示华华对手获得一分):
WWWWWWWWWWWWWWWWWWWWWWLW
在11分制下,此时比赛的结果是华华第一局11比0获胜,第二局11比0获胜,正在进行第三局,当前比分1比1。
而在21分制下,此时比赛结果是华华第一局21比0获胜,正在进行第二局,比分2比1。
如果一局比赛刚开始,则此时比分为0比0。
你的程序就是要对于一系列比赛信息的输入(WL形式),输出正确的结果。
输入格式:
每个输入文件包含若干行字符串(每行至多20个字母),字符串由大写的W、L和E组成。
其中E表示比赛信息结束,程序应该忽略E之后的所有内容。
输出格式:
输出由两部分组成,每部分有若干行,每一行对应一局比赛的比分(按比赛信息输入顺序)。
其中第一部分是11分制下的结果,第二部分是21分制下的结果,两部分之间由一个空行分隔。
输入样例:
WWWWWWWWWWWWWWWWWWWW
WWLWE
输出样例:
11:0
11:0
1:1
21:0
2:1
题解:
本题关键在于如何储存输入的数据,与判断一局比赛结束的条件。
#include<iostream>
using namespace std;
int main()
{
char x[10000],q;
int i=0,a,b,j=0,m=0;
while(cin>>x[i]) //输入数据
{
i++;
if(x[i]=='E')break;
}
while(j<i-1) //11分赛制的情况
{
a=0,b=0; //a与b表示双方在每一局的得分
for(j=m;j<=i;j++) //循环每一回合
{
if(x[j]=='W')a++;
else if(x[j]=='L')b++;
//当分出胜负或检测到E时输出比分情况
if(a>=11&&a-b>=2||b>=11&&b-a>=2||x[j]=='E')
{
cout<<a<<':'<<b<<endl;
break; //break结束本局
}
}
m+=(a+b); //每一局结束后,下一局要从数组下标m开始循环
}
cout<<endl;
m=0,j=0;
while(j<i-1) //21分赛制的情况,接下来思路同上,不再赘述
{
a=0,b=0;
for(j=m;j<=i;j++)
{
if(x[j]=='W')a++;
else if(x[j]=='L')b++;
if(a>=21&&a-b>=2||b>=21&&b-a>=2||x[j]=='E')
{
cout<<a<<':'<<b<<endl;
break;
}
}
m+=(a+b);
}
return 0;
}
2、高精度加法
题目描述:
对于输入的两个不超过100位数字的非负整数,给出两数之和。
输入格式:
在两行中分别给出两个不超过100位数字的非负整数
输出格式:
在一行中输出两数之和
输入样例:
123
12
输出样例:
135
思路:
100位数字过大,想到用数组来储存每一位数字 。本人分为了两种情况(其实应该是可以合并的)
#include<iostream>
#include<string.h>
using namespace std;
int main()
{
char a[100],b[100];
scanf("%s",&a);
scanf("%s",&b);
int t1=strlen(a),t2=strlen(b),js=0;
if(t1>=t2) //当数组a表示的数字位数更大或相等时
{
for(int i=t1-1;i>=0;i--,t2--)
{
if(t2>=1)a[i]+=b[t2-1]-'0'; //从各自的个位数开始相加
if(a[i]>'9') //判断是否要进位
{
a[i]-=10;
if(i==0)js=1; //标记是最大的一位数需要进位的情况
else a[i-1]++; //若要进位则大的一位数加一
}
}
if(js==1)cout<<"1"; /*若最大的一位数要进位,由于a[0]已经是最大的一位数,且
进位只可能进一,所以若进位则先输出一个1作为结果的最高位*/
for(int m=0;m<t1;m++)cout<<a[m];
}
else //当数组b表示的数字位数更大时,下同。
{
for(int i=strlen(b)-1;i>=0&&t1>=1;i--,t1--)
{
if(t1>=1)b[i]+=a[t1-1]-'0';
if(b[i]>'9')
{
b[i]-=10;
if(i==0)js=1;
else b[i-1]++;
}
}
if(js==1)cout<<"1";
for(int m=0;m<strlen(b);m++)cout<<b[m];
}
return 0;
}
3、高精度求累加和
题目描述:
使用求和公式求1到N的累加和大家都会,但是如果把N值变大呢,比如100位的整数,那该怎么求?
输入格式:
输入在一行中给出1个位数不超过100位的整数N。
输出格式:
对每一组输入,在一行中输出1+2+3+……+N的值。
输入样例:
在这里给出一组输入。例如:
10
输出样例:
在这里给出相应的输出。例如:
55
代码长度限制:16 KB
时间限制:100 ms
内存限制:64 MB
题解:
这题最恶心的地方是时间限制,对算法的要求很高,利用循环累加的算法会超时,因此必须用巧妙的算法。本人利用等差数列求和公式【(N+1)*N】/ 2 ,则接下来的难点就在于如何利用小学数学老师教咱们的竖式乘法。
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char a[100],b[101],c[100],d[10000];
//数组a用于输入,数组b用来表示N+1,数组c用来表示N,数组d储存结果
//细节:b长度定为101是考虑到输入的数可能为100位数且数字均为9,此时加一就会进位
memset(d,'0',sizeof(d)); //初始化数组d,初始为字符0
int i=0,js=0,flag=0,q;
while(scanf("%c",&a[i])!='\n')
{
if(a[i]!='\n')i++;
else break;
}
for(int m=i-1,j=0;m>=0;m--,j++) //逆序存放,以便进位
{
b[j]=a[m];
c[j]=a[m];
if(c[j]!='9')flag=1;
}
b[0]++,b[i]='0'; //求N+1
int m=0,s0;
while(b[m]>'9') //讨论要进位的情况
{
b[m]='0';
b[++m]++;
}
int t=i;
if(flag==0)t++; //因为当c数组表示9、99、999等等时数组b的长度就成了i+1
for(int j=0;j<i;j++)
{
s0=0; //用s0表示进位时要进多少
for(q=0;q<t;q++)
{
int s=(b[q]-'0')*(c[j]-'0');
d[q+j]+=s%10+s0;
s0=s/10; //讨论需要进位的情况,若进位则进s0
while(d[q+j]>'9') //此处不能用if,因为在此时d[q+j]-'0'有可能>=20
{
d[q+j]-=10;
s0++;
}
}
if(s0!=0)d[q+j]+=s0;
}
flag=0;
for(js=9999;js>=0;js--)
if(d[js]!='0')break;
for(int j=js;j>=0;j--) //N*(N+1)后还要除以2,且从最高位数开始除。
{
if((d[j]-'0')%2==0)d[j]=(d[j]-'0')/2+'0'; //分两种情况:偶数或奇数
else
{
d[j]=(d[j]-'0')/2+'0';
d[j-1]+=10;
}
if(d[j]!='0'||flag==1)
{
cout<<d[j];
flag=1;
} //由于最高位为1时对2整除后变为0,则考虑若最高位数为0则不输出,依此类推
}
return 0;
}
NEUQ-ACM CLUB 2022招新题前六题:
网址:https://blog.csdn.net/swcj240031/article/details/127619113