比赛算法入门day1——高精度与其它模拟

高精

高精:数据类型的容纳的数字范围有限,有时需要用数组来模拟非常长的整数。



代码:


//高精加法 
#include<bits/stdc++.h>
using namespace std;
#define maxn 510
int a[maxn],b[maxn],c[maxn];
int main()
{
	string A,B;
	cin>>A>>B;
	int len=max(A.length(),B.length());
	for(int i=A.length()-1,j=0;i>=0;i--,j++) 
	{
		a[j]=A[i]-'0';
	}
	for(int i=B.length()-1,j=0;i>=0;i--,j++) 
	{
		b[j]=B[i]-'0';
	}//倒序存入数组 
	for(int i=0;i<len;i++)
	{
		c[i]+=a[i]+b[i];
		c[i+1]+=c[i]/10;//模拟进位 
		c[i]%=10;
	}
	if(c[len])len++;//如果最后一次发生进位,位数自加1 
	for(int i=len-1;i>=0;i--)cout<<c[i];
	return 0;
}



//高精乘法 
//先计算每一位贡献再处理进位
#include<bits/stdc++.h>
#define maxn 4100
using namespace std;
int a[maxn],b[maxn],c[maxn];
int main()
{
	string A,B;
	cin>>A>>B;
	if(A=="0"||B=="0")cout<<0;//乘积为0的情况单独考虑 
	else
	{
		int lena=A.length(),lenb=B.length();
		for(int i=lena-1;i>=0;i--)a[lena-1-i]=A[i]-'0';
		for(int i=lenb-1;i>=0;i--)b[lenb-1-i]=B[i]-'0';//逆序存入数组
		for(int i=0;i<lena;i++)
			for(int j=0;j<lenb;j++)
				c[i+j]+=a[i]*b[j];//计算每一位贡献 	
		int len=lena+lenb;
		for(int i=0;i<len;i++)
		{
			c[i+1]+=c[i]/10;
			c[i]%=10;	
		}//处理进位
		while(!c[len-1])
			len--;
		for(int i=len-1;i>=0;i--)
			cout<<c[i]; 
	}
 	return 0;
} 


模拟

模拟:找不到更加高效的做法时,题目怎么描述就让程序怎么运行。



P1042 [NOIP2003 普及组] 乒乓球

题目描述:

华华通过以下方式进行分析,首先将比赛每个球的胜负列成一张表,然后分别计算在11分制和21分制下,双方的比赛结果(截至记录末尾)。

比如现在有这么一份记录,(其中W表示华华获得一分,L表示华华对手获得一分):

WWWWWWWWWWWWWWWWWWWWWWLW

在11分制下,此时比赛的结果是华华第一局11比0获胜,第二局11比0获胜,正在进行第三局,当前比分11比11。而在21分制下,此时比赛结果是华华第一局21比0获胜,正在进行第二局,比分2比1。如果一局比赛刚开始,则此时比分为0比0。直到分差大于或者等于2,才一局结束。

你的程序就是要对于一系列比赛信息的输入(WLWL形式),输出正确的结果。

代码如下:

#include<bits/stdc++.h>
using namespace std;
int sz[2]={11,21};//代表两种分制
bool a[25*2500];
int main()
{
	char tmp;//tmp有“临时”的含义 
	int n=0; 
	while(1)
	{
		cin>>tmp;
		if(tmp=='E')break;
		else if(tmp=='W')a[n++]=1;//华华赢 
		else if(tmp=='L')a[n++]=0;//华华输 
	}
	for(int k=0;k<2;k++)
	{
		int w=0,l=0;
		for(int i=0;i<n;i++)
		{
			w+=a[i];l+=1-a[i];
			if(max(w,l)>=sz[k]&&abs(w-l)>=2)//达到对应分数并超出对手两分 
			{
				cout<<w<<":"<<l<<endl;
				w=l=0;
			}
		}
		//if(w!=0||l!=0)
		//此处不需要的原因只要一局比赛结束就马上开启了下一局
		//因此即便没有比分也要输出0:0 
		cout<<w<<":"<<l<<endl;
		cout<<endl;
	}
	return 0;
} 

P2670 [NOIP2015 普及组] 扫雷游戏

题目描述

扫雷游戏是一款十分经典的单机小游戏。在n行m列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有多少个是地雷格。游戏的目标是在不翻出任何地雷格的条件下,找出所有的非地雷格。

现在给出n行m列的雷区中的地雷分布,要求计算出每个非地雷格周围的地雷格数。

输入 3 3
*? ?
???
?*?
输出 *10
221
1*1

代码如下:

#include<bits/stdc++.h>
using namespace std;
const int dx[]={1,1,1,-1,-1,-1,0,0};//代表x方向偏移量 
const int dy[]={1,0,-1,1,0,-1,1,-1};//代表y方向偏移量 
char p[102][102];
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			cin>>p[i][j];
	for(int i=1;i<=n;i++)
	{
	
		for(int j=1;j<=m;j++)
		{
			if(p[i][j]=='*')cout<<"*";
			else
			{
				int cnt=0;//cnt有计数器的含义 
				for(int k=0;k<8;k++)
				{
					if(p[i+dx[k]][j+dy[k]]=='*')cnt++;
				}//这样表示更加简洁 
				cout<<cnt;
			}
			
		}
		cout<<endl;
	}
	return 0;
} 
posted @ 2021-01-30 23:13  菜鸟侦探乐  阅读(122)  评论(0)    收藏  举报