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

思路如下:

先用数组来存储这些字符,1代表W,-1代表L,0代表E,然后遍历该数组,根据规则输出结果即可
注意:乒乓球比赛只有当分差大等于2分时才会结束,例如:11:10时,21:20时,比赛是不会结束的!( ˚ཫ˚ )

完整代码如下:

#include<bits/stdc++.h>
using namespace std;    
int len=0;
int win=0;   //胜利的次数
int lose=0;   //失败的次数
char str[55555];   //比赛的情况
void game(int n){   //n表示是11分制,还是21分制
	lose=0;
	win=0;
	for(int i=0;i<len;i++){
		if(str[i]=='W'){
			win++;
		}
		else if(str[i]=='L'){
			lose++;
		}
		if(str[i]=='E'){   
		//如果比赛结束,跳出循环,直接输出现在的比分
			break;
		}
		if(win>=n||lose>=n){
			if(abs(win-lose)>=2){ 
				cout<<win<<":"<<lose<<endl;
				win=0;
				lose=0;   //输出完成后要归零
			}
		}
	}
	cout<<win<<":"<<lose;   //如果比赛刚刚开始或者还没有比完,或者结束了
	return ;
}
int main(){
	char a;
	while(cin>>a){
		if(a=='W'||a=='L'){
			str[len]=a;		
			len++;
		}
		else if(a=='E'){
			str[len]=a;
			break;
			}		
		}	  //输入比赛情况
	game(11);   //11分制
	cout<<endl<<endl;  //注意,在11分制和21分制之间要有两个两个换行
	game(21);	  //21分制
return 0;
} 

2.高精度加法:

对于输入的两个不超过100位数字的非负整数,给出两数之和。
输入格式:
在两行中分别给出两个不超过100位数字的非负整数
输出格式:
在一行中输出两数之和
输入样例:
123
12
输出样例:
135

本题需要高精度加法的知识,具体什么是高精度加法呢?就是将需要相加的两个数的每个位置上的数字取出来,存放到一个数组里面,例如135,变成1 3 5;然后根据小学就学过的加法进行相加,并输出结果就行了,是不是很简单•⌄•.

完整代码如下:

#include<bits/stdc++.h>
using namespace std;    
string a1,b1;  //需要输入的两个数,必须用字符或者字符串形式存储(数据太大了,整形放不下)
int anum=0;   
int bnum=0;   //
int len=0;  
int len1,len2;    //两个数的位数
int sumnum[110]={0};
int a_num[105]={0};   //数字a的各个位置上的数字
int b_num[105]={0};   //数字b的各个位置上的数字
char a[105],b[105];   //将字符串的各个字符存放到字符数组里,方便将字符转化为数字
void turn(int x1,int x2){   //将字符串的各个字符存放到字符数组里
	for(int i=0;i<x1;i++){
		a[i]=a1[i];
	}
	for(int i=0;i<x2;i++){
		b[i]=b1[i];
	}	
}
int main(){
    cin>>a1>>b1;
    len1=a1.length();  
    len2=b1.length();  //求出两个数的位数
    turn(len1,len2);  //将字符串的各个字符存放到字符数组里
    for(int i=len1-1;i>=0;i--){  
    	a_num[anum++]=a[i]-'0';
	}
    for(int i=len2-1;i>=0;i--){
    	b_num[bnum++]=b[i]-'0';   //将字符转化为数字,减去'0'即可,这里是倒序存的,方便之后的相加
	}
	int len=max(anum,bnum);   //去两个数较大位数的位数
	for(int i=0;i<len;i++){
		sumnum[i]+=(a_num[i]+b_num[i]);   //相同位数的数字相加
		sumnum[i+1]+=((a_num[i]+b_num[i])/10);  //进位
		sumnum[i]%=10;  //要对10取余
		if(sumnum[len]>0){
			len++;   //如果最高位之后有进位,说明位数需要加长
		}
	}
	for(int j=len-1;j>=0;j--){
		cout<<sumnum[j];  //倒序输出最后结果
	}
    return 0;
}

3.高精度求累加和

使用求和公式求1到N的累加和大家都会,但是如果把N值变大呢,比如100位的整数,那该怎么求?
输入格式:
输入在一行中给出1个位数不超过100位的整数N。
输出格式:
对每一组输入,在一行中输出1+2+3+……+N的值。
输入样例:
在这里给出一组输入。例如:
10
输出样例:
在这里给出相应的输出。例如:
55

此题显然不能累加,需要用到累加的公式:(a1(1)+an(n))n/2,那么这就需要高精度的乘法和除法了那么什么是高精度的乘法呢?回想一下刚才的高精度加法,再回想一下小学学的乘法你就能知道,乘法在运算时需要加法,那么就可以根据加法写出乘法;那怎么解决除法呢?除法其实就是另一种乘法,比如除以2其实就是乘以0.5,所以就可以写出答案.๐•ᴗ•๐

完整代码如下:

#include<iostream>
using namespace std;
char a[250];    //存放输入的数字各个位上的数字
string b;   //用字符串存放输入的数字
int b_num[250]={0};  //初始化数组
void turnstr(int len){   //将字符串的字符存放到字符数组里
    for(int i=0;i<len;i++){
        a[i]=b[i];
    }
    return ;
}
void turnnum(int len){   //将字符数组的字符变为数字
    for(int i=0;i<len;i++){
        b_num[i]=a[i]-'0';
    }
    return ;
}
int main(){
    int start,x;  
    int b2[250]={0};   //用于存放最终的结果
    cin>>b;   //输入数字
    int len1=b.length();   //获取数字的长度
    turnstr(len1);  //转化为字符数组
    turnnum(len1);  //转化为数组
    int b1_num[250];  
    for(int i=0;i<250;i++){
    	b1_num[i]=b_num[i];
	}
    b1_num[len1-1]+=1;   //获取b+1的结果
//高精度乘法:
    for(int i=len1-1;i>=0;i--){
        start=len1-i-1;  //每次加的起点都要变化,都要往前移一位
        for(int j=len1-1;j>=0;j--){
            b2[start]+=b_num[i]*b1_num[j];  //获取该位置上相加后的结果
            start++;   //位置每次都要向前移一位
            x=start;  //获取最后的数组长度
        }
    }
    for(int i=0;i<x;i++){
        b2[i+1]+=b2[i]/10;  //开始进位
        b2[i]%=10;
        if(b2[x]>0){
            x++;  //如果最高位大于0,说明数组长度需要扩大
        }
    }
//高精度除法(其实就是乘以0.5):
    for(int i=0;i<x;i++){
        b2[i]*=5;  //每个位置都乘以5
    }
    for(int i=0;i<x;i++){   //开始进位
        b2[i+1]+=b2[i]/10;
        b2[i]%=10;
        if(b2[x]>0){
            x++;
        }
    }
    for(int i=x-1;i>=1;i--){   //最后结尾只能为1,不能是0,因为乘以0.5,小数点需要向后移一位
        cout<<b2[i];
    }
    return 0;
}

完美结束₍˄·͈༝·͈˄₎◞ ̑̑ෆ⃛

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值