NEUQ-ACM预备队训练-week1(模拟与高精度)

国际乒联现在主席沙拉拉自从上任以来就立志于推行一系列改革,以推动乒乓球运动在全球的普及。

其中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

#include<iostream>
#include<string>
using namespace std;
int main()
{
	long w=0,l=0,n=0,a[12526]={0};//w:华华胜场 l:华华负场 n:总场数 a[n]:第n场华华胜负情况(1为胜,-1为负)
    char m;
	while(m!='E')
	{
		cin>>m;//输入字符m,并转化为对应胜负情况储存在a[]中
        if(m=='W')a[n]=1;
        else if(m=='L')a[n]=-1;
		n++;
	}
	for(int i=0;i<n;i++)//11分制的情况
	{
		if(a[i]==1)
		{
			w+=1;
		}
		else if(a[i]==-1)
		{
			l+=1;
		}
        if(i==n-1)
		{
			cout<<w<<":"<<l<<endl;
            break;
		}
		if((w>=11||l>=11)&&((w-l>=2)||(l-w>=2)))//分差至少2分且至少有11分时进入下一局并输出
		{
			cout<<w<<":"<<l<<endl;
			w=0;
			l=0;
			continue;
		}
	}
   	cout<<endl;
	w=0;
	l=0;//胜场归零
		for(int i=0;i<n;i++)
	{
		if(a[i]==1)
		{
			w+=1;
		}
		else if(a[i]==-1)
		{
			l+=1;
		}
        if(i==n-1)
		{
			cout<<w<<":"<<l;
            break;
		}
		if((w>=21||l>=21)&&((w-l>=2)||(l-w>=2)))//分差至少2分且至少有21分时进入下一局并输出
		{
			cout<<w<<":"<<l<<endl;
			w=0;
			l=0;
			continue;
		}
	}
	return 0;
}

 

7-2 高精度加法

分数 15

全屏浏览题目

切换布局

作者 周强

单位 青岛大学

对于输入的两个不超过100位数字的非负整数,给出两数之和。

输入格式:

在两行中分别给出两个不超过100位数字的非负整数

输出格式:

在一行中输出两数之和

输入样例:

123
12

输出样例:

135

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

基本思路:用string存储数据并进行运算

#include<iostream>
#include<string>
using namespace std;
int main()
{
	int carry=0;//初始化进位为0
	string a,b,c;//a和b为两个加数
	cin>>a>>b;
	if(a.size()>=b.size())
	{
		for(int i=1;i<=a.size()-b.size();i++)
		{
			c+='0';
		}
		c+=b;
		b=c;
	}
	else if(a.size()<b.size())
	{
		for(int i=1;i<=b.size()-a.size();i++)
		{
			c+='0';
		}
		c+=a;
		a=c;
	}//这里当a和b位数不一致时通过在前方补0的方式对齐a和b
	for(int i=a.size()-1;i>=0;i--)
	{
		c[i]=(char)((int)a[i]+(int)b[i]-(int)'0'+carry);
		carry=0;
		if(c[i]>'9')//大于9时进位,并把该位减10
		{
			c[i]-=10; 
			carry=1;
		}
	}
	if(a=="0"){cout<<b<<endl;}
	else if(b=="0"){cout<<a<<endl;}
	if(carry==1){cout<<1;}//逐位进行加法后若有进位,在最前方补“0”
	cout<<c;
}

7-3 高精度求累加和

分数 25

全屏浏览题目

切换布局

作者 胡伟平

单位 广西科技大学

使用求和公式求1到N的累加和大家都会,但是如果把N值变大呢,比如100位的整数,那该怎么求?

输入格式:

输入在一行中给出1个位数不超过100位的整数N。

输出格式:

对每一组输入,在一行中输出1+2+3+……+N的值。

输入样例:

在这里给出一组输入。例如:

10

输出样例:

在这里给出相应的输出。例如:

55

代码长度限制

16 KB

时间限制

100 ms

内存限制

 64 MB

思路:使用等差数列求和公式S=(n+1)*n/2,考虑到数据远大于long long范围,使用string存储数据并运算 

#include<iostream>
#include<string>
using namespace std;
string add(string a,string b)//将上一题的代码写成add函数,以便后续使用
{	
	int carry=0;
	string c;
	if(a.size()>=b.size())
	{
		swap(a,b);
	}
	for(int i=1;i<=b.size()-a.size();i++)
	{
		c+='0';
	}
	c+=a;
	a=c;
	for(int i=a.size()-1;i>=0;i--)
	{
		c[i]=(char)((int)a[i]+(int)b[i]-(int)'0'+carry);
		carry=0;
		if(c[i]>'9')
		{
			c[i]-=10; 
			carry=1;
		}
	}
	if(carry)c="1"+c;
	return c;
}
int num(char x)//将char数字转变为int数字
{
	return (x-'0'); 
}
string mul(string a,string b)//乘法函数
{
	string s="0",ts="0";
	int la=a.size(),lb=b.size(),carry=0;
	for(int i=la-1;i>=0;i--)
	{
		
		for(int j=lb-1;j>=0;j--)
		{
			ts="0";
			string t="0";
			t=(char)((num(a[i])*num(b[j])+carry)%10+(int)'0');
			carry=((num(a[i])*num(b[j])+carry)/10);
			for(int k=0;k<=la+lb-i-j-3;k++)
			{
				t=t+"0";
			}
			ts=add(ts,t);
			if(carry!=0)
			{
				ts=(char)((int)'0'+carry)+ts;
				carry=0;
			}
			s=add(s,ts);
		}	
	}
	
	return s;
}
int main()
{
	string a,b,s;
	cin>>a;
	b=add(a,"1");
	s=mul(a,b);
	s=mul(s,"5");
	s.erase(s.size()-1);
	cout<<s<<endl;
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值