模拟与高精度
1-1 乒乓球
题目描述:
国际乒联现在主席沙拉拉自从上任以来就立志于推行一系列改革,以推动乒乓球运动在全球的普及。
其中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
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
思路分析:
纯模拟,注意分差大于2才能结束即可。
参考代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+5;
int a1[maxn],a2[maxn],b1[maxn],b2[maxn];
int main()
{
char c;
int n1=0,n2=0,m1=0,m2=0,k1=0,k2=0;
while (cin>>c&&c!='E')
//若用scanf读入,注意它不会跳过空格与回车
{
if (c=='W')
n1++,m1++;
else
n2++,m2++;
if (n1>=11&&(n1-n2)>=2)
{
a1[++k1]=n1;
a2[k1]=n2;
n1=0;
n2=0;
}
else if (n2>=11&&(n2-n1)>=2)
{
a1[++k1]=n1;
a2[k1]=n2;
n1=0;
n2=0;
}
if (m1>=21&&(m1-m2)>=2)
{
b1[++k2]=m1;
b2[k2]=m2;
m1=0;
m2=0;
}
else if (m2>=21&&(m2-m1)>=2)
{
b1[++k2]=m1;
b2[k2]=m2;
m1=0;
m2=0;
}
}
if (n1!=0||n2!=0)
{
a1[++k1]=n1;
a2[k1]=n2;
}
if (m1!=0||m2!=0)
{
b1[++k2]=m1;
b2[k2]=m2;
}
for (int i=1; i<=k1; i++)
printf("%d:%d\n",a1[i],a2[i]);
printf("\n");
for (int i=1; i<=k2; i++)
printf("%d:%d\n",b1[i],b2[i]);
// system("pause");
return 0;
}
1-2 高精度加法
题目描述:
对于输入的两个不超过100位数字的非负整数,给出两数之和。
输入格式:
在两行中分别给出两个不超过100位数字的非负整数
输出格式:
在一行中输出两数之和
输入样例:
123
12
输出样例:
135
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
思路分析:
高精度的板子题,用数字存储各个位置上的数据,注意进位的处理。
参考代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=105;
char a[maxn],b[maxn];
int x[maxn],y[maxn];
int a_len,b_len,len;
void to_int()
{
a_len=strlen(a+1); //用a+1读入字符串,strlen就需要a+1
b_len=strlen(b+1);
for (int i=1,j=a_len; j>=1; i++,j--)
{
x[j]=a[i]-'0';
}
for (int i=1,j=b_len; j>=1; i++,j--)
{
y[j]=b[i]-'0';
}
return;
}
void addition()
{
int tran=0; //记录进位数
len=max(a_len,b_len);
for (int i=1; i<=len+1; i++)
{
tran=x[i]+y[i]+tran;
x[i]=tran%10;
tran/=10;
}
return;
}
void print()
{
len++;
while (x[len]==0) //避免前导零的出现
len--;
for (int i=len; i>=1; i--)
printf("%d",x[i]);
}
int main()
{
scanf("%s\n%s",a+1,b+1); //用a+1,可以避免数组下标为0
to_int(); //转为数组中,并且顺序翻转
addition(); //相加
print(); //打印
//system("pause");
return 0;
}
1-3 高精度求累加和
题目描述:
使用求和公式求1到N的累加和大家都会,但是如果把N值变大呢,比如100位的整数,那该怎么求?
输入格式:
输入在一行中给出1个位数不超过100位的整数N。
输出格式:
对每一组输入,在一行中输出1+2+3+……+N的值。
输入样例:
在这里给出一组输入。
例如:
10
输出样例:
在这里给出相应的输出。
例如:
55
代码长度限制
16 KB
时间限制
100 ms
内存限制
64 MB
思路分析:
直接累加显然会超时,所以想到直接用累加求和的公式:N*(N+1)/2。需要用到高精度加、乘、除。
参考代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=200+5;
int a[maxn],b[maxn],c[maxn];
int read()
{
char c[maxn];
scanf("%s",c+1);
int len=strlen(c+1);
for (int i=1,j=len; i<=len; i++,j--)
a[j]=c[i]-'0';
return len;
}
int main()
{
int len1=read();
for (int i=1; i<=len1; i++)
b[i]=a[i];
a[1]+=1;
for (int i=1;i<=len1; i++)
{
if (a[i]==10)
{
a[i]=0;
a[i+1]++;
}
else break;
}
len1++;
for (int i=1;i<=len1; i++)
for (int j=1; j<=len1; j++)
{
c[i+j-1]+=a[i]*b[j];
c[i+j]+=c[i+j-1]/10;
c[i+j-1]%=10;
}
len1*=2;
while (!c[len1])
len1--;
memset(a,0,sizeof(a));
for (int i=1,j=len1; i<=len1; i++,j--)
a[i]=c[j];
int tran=0;
for (int i=1; i<=len1; i++)
{
a[i]+=tran*10;
tran=a[i]%2;
a[i]/=2;
}
int l=1;
while (!a[l])
l++;
for (int i=l; i<=len1; i++)
printf("%d",a[i]);
//system("pause");
return 0;
}
参考博客
[1]:https://maureen.blog.csdn.net/article/details/109912035

1706

被折叠的 条评论
为什么被折叠?



