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

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
内存限制

64MB

 题解

 主要是把数据存进数组里然后操作

#include 
#include 
using namespace std;

int main()
{
	char a[99999]={};
	char c;

	int L = 0;
	int e = 0;
	int w = 0;
	int l = 0;
	while (cin >> c && c != 'E') {
		a[L] = c;
		L++;
	}
	a[L] = 'E';
    while (true) {
		if (a[e] == 'W') {
			w++;
		}
		if (a[e] == 'L') {
			l++;
		}
		if (max(w, l) >= 11 && fabs(w - l) >= 2) {
			cout << w << ":" << l << endl;
			w = 0;
			l = 0;
		}
		if (a[e]=='E') {
			cout << w << ":" << l << endl;
			w = 0;
			l = 0;
			break;
		}
			e++;
	}
	e = 0; w = 0; l = 0;
    cout<= 21 && fabs(w - l) >= 2) {
			cout << w << ":" << l << endl;
			w = 0;
			l = 0;
		}
		if (a[e] == 'E') {
			cout << w << ":" << l << endl;
			w = 0;
			l = 0;
			break;
		}
		e++;
	}
}

2.高精度加法

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

输入格式:

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

输出格式:

在一行中输出两数之和

输入样例:

123
12

 输出样例:

135 

 代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB 

题解: 

用两个数组模拟纸上计算时的竖式

#include
#include
using namespace std;
int a[1000];
int b[1000];
int main()
{
	string c;
	string d;
	cin >> c >> d;
	int cishu = max(c.size(), d.size());
	for (int e = 0; e < c.size(); e++) {
		a[e] = c[c.size() - 1 - e] - '0';
	}
	for (int e = 0; e < d.size(); e++) {
		b[e] = d[d.size() - 1 - e] - '0';
	}
	for (int e = 0; e < cishu; e++) {
		//cout << cishu << "cishu"< 0; e--)
	{
		cout << a[e-1];
	}
		
		system("pause");
	return 0;
}

3. 高精度求累加和

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

输入格式:

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

输出格式:

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

输入样例:

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

10

输出样例:

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

55

代码长度限制

16 KB

时间限制

100 ms

内存限制

64 MB

题解: 

用数组模拟竖式之后再套用高精度加法的法子

#include
#include
using namespace std;
int a[1000];//上面的数组
int b[1000];//下面的数组
int bb[10000] = { 0 };//用来存结果的数组
int bbb[1] = { 0 };//除了用来加一没啥用

int main()
{
	bbb[0] = 1;
	string c;
	cin >> c;
	int shangmianshuzuchicun = c.size();
	int xiamianshuzuchicun = c.size();
	int zhong = 0;
	for (int e = 0; e < shangmianshuzuchicun; e++) {
		a[e] = c[shangmianshuzuchicun - 1 - e] - '0';
		b[e] = c[shangmianshuzuchicun - 1 - e] - '0';
	}
	for (int e = 0; e < 1; e++) {
		a[e] += bbb[e];
		a[e + 1] += a[e] / 10;
		a[e] %= 10;
	}//完成加一,上面的数
	if (a[shangmianshuzuchicun]) {
		shangmianshuzuchicun++;
	}
	int shangmianshuzuchicun2 = shangmianshuzuchicun;//备份下面数组尺寸
	//cout << "a";
	//for (int e = shangmianshuzuchicun; e > 0; e--) {
	//	cout << a[e - 1];
	//}
	//cout << endl;
	//cout << "b";
	//for (int e = xiamianshuzuchicun; e > 0; e--) {
	//	cout << b[e - 1];
	//}
	//cout << endl;
	int huancun = 0;//用于周转数据
	int j = 0;//用于进位
	int tuijin = 0;//用于下面加法位置前移
	int jieguoweishu = 0;
	for (int xiamian = 0; xiamian < xiamianshuzuchicun; xiamian++) {
		shangmianshuzuchicun = shangmianshuzuchicun2;//还原被修改的上位尺寸
		for (int shangmian = 0; shangmian < shangmianshuzuchicun; shangmian++) {
			//cout << shangmian + 1 << "循环次数" << endl;
			//完成下面单个数轮流和上面的数相乘,再加上后面的进位
			huancun = a[shangmian] * b[xiamian] + j;
			//cout << huancun << " " << a[shangmian] << "和" << b[xiamian] << "两数相乘加进位" << j << endl;
			//确定这个位置乘完以后最终的结果,加号表示下一次乘法运算时加上之前上方对应的值
			bb[shangmian + tuijin] += huancun;//目前缓存存储的是本次两数相乘的直接结果加上后一位进的值
			//cout << bb[shangmian + tuijin] << "确定这个位置乘完以后最终的结果,加号表示下一次乘法运算时加上之前上方对应的值" << endl;
			//计算需要进位多少
			j = bb[shangmian + tuijin] / 10;
			//cout << j << "计算需要进位多少" << endl;
			//算出这个位置运算后最终剩下什么数
			bb[shangmian + tuijin] %= 10;
			//cout << shangmian + tuijin << "bb[0]" << endl;
			//cout << bb[shangmian + tuijin] << "算出这个位置运算后最终剩下什么数" << endl;
			//计算最终结果的长度,最终结果的长度应该为最后一次乘法运算时推进次数加上面数组的长度,
			//如果最后一次乘法进位大于0,则再加一
			if (xiamian == xiamianshuzuchicun - 1) {
				jieguoweishu = tuijin + shangmianshuzuchicun;
				if (shangmian == shangmianshuzuchicun - 1 && j > 0) {
					jieguoweishu++;
					//cout << jieguoweishu << "结果位数" << endl;
				}
			}
			//接收最后的j
			if (shangmian == shangmianshuzuchicun - 1 && j > 0) {
				shangmianshuzuchicun++;
				//cout << shangmianshuzuchicun << "上面数组尺寸" << endl;
			}
			//cout << endl;
		}
		tuijin++;
	}
	//for (int e = jieguoweishu; e > 0; e--) {
	//	cout << bb[e - 1];
	//}
	//cout << endl;
	// int buchong = jieguoweishu;
	int buchong = jieguoweishu;
	if (bb[jieguoweishu - 1] == 1) {
		buchong -= 1;
	}
	//把结果除以二
	int yvshu = 0;//用于退位,即除剩的数
	for (int e = jieguoweishu; e > 0; e--) {
		huancun = bb[e - 1];
		//cout << bb[e - 1] << "bb[" << e - 1 << "]" << endl;
		bb[e - 1] = (bb[e - 1] + (yvshu * 10)) / 2;//本位应该是的值
		yvshu = huancun % 2;
		//cout << bb[e - 1] << "bb[" << e - 1 << "]" << endl;
		//cout << endl;
	}
	//输出n(n+1)
	for (int e = buchong; e > 0; e--) {
		cout << bb[e - 1];
	}
	system("pause");
	return 0;
}

你可能感兴趣的:(c++,算法,数据结构)