ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

5月20号洛谷题单刷题总结(模拟算法和高精度)

2021-05-21 19:57:44  阅读:267  来源: 互联网

标签:11 ... 单刷题 20 地雷 格子 int John 号洛谷题


模拟算法和高精度


不多说了,进入正题

P1042 [NOIP2003 普及组] 乒乓球

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

比如现在有这么一份记录,(其中W表示华华获得一分,L表示华华对手获得一分):
WWWWWWWWWWWWWWWWWWWWWWLW
在11分制下,此时比赛的结果是华华第一局11比0获胜,第二局11比0获胜,正在进行第三局,当前比分1比1。而在21分制下,此时比赛结果是华华第一局21比0获胜,正在进行第二局,比分2比1。如果一局比赛刚开始,则此时比分为0比0。直到分差大于或者等于22,才一局结束。
你的程序就是要对于一系列比赛信息的输入(WL形式),输出正确的结果。
输入格式
每个输入文件包含若干行字符串,字符串有大写的W、L和E组成。其中EE表示比赛信息结束,程序应该忽略E之后的所有内容。
输出格式
输出由两部分组成,每部分有若干行,每一行对应一局比赛的比分(按比赛信息输入顺序)。其中第一部分是11分制下的结果,第二部分是21分制下的结果,两部分之间由一个空行分隔。
输入:
WWWWWWWWWWWWWWWWWWWW
WWLWE
输出:
11:0
11:0
1:1

21:0
2:1
分析:
这是某一次我们的考试题。
注意输入的时候,碰到E就停止。
11分制和21分制的要分开写。
所以也要分开输出。
并且还要注意11分制写完之后,把计数器清零!!!!!

#include<bits/stdc++.h>
using namespace std;
char s;
string a;
long long w,l,i;
int main()
{
	while(cin>>s && s !='E'){
		if(s=='\n'){
			continue;
		}
		i++;
		if(s == 'W'){
			w++;
			a += s;
		}
		if(s == 'L'){
			l++;
			a += s;
		}
		if((w >= 11 || l >= 11)&&(w-l>=2||l-w>=2)){
			cout<<w<<':'<<l<<endl;
			w=0,l=0;	
		}
	}
	cout<<w<<':'<<l<<endl<<endl;
	w=0,l=0;
	for(int j=0;j<i;j++){
		if(a[j] == 'W'){
			w++;
		}
		if(a[j] == 'L'){
			l++;
		}
		if((w >= 21 || l >= 21)&&(w-l>=2||l-w>=2)){
			cout<<w<<':'<<l<<endl;
			w=0,l=0;
		}
	}
	cout<<w<<':'<<l<<endl;
	return 0;
}

P2670 [NOIP2015 普及组] 扫雷游戏

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

现在给出n行m列的雷区中的地雷分布,要求计算出每个非地雷格周围的地雷格数。
注:一个格子的周围格子包括其上、下、左、右、左上、右上、左下、右下八个方向上与之直接相邻的格子。

输入格式
第一行是用一个空格隔开的两个整数n和m,分别表示雷区的行数和列数。
接下来n行,每行m个字符,描述了雷区中的地雷分布情况。字符’’表示相应格子是地雷格,字符’?’表示相应格子是非地雷格。相邻字符之间无分隔符。
输出格式
输出文件包含n行,每行m个字符,描述整个雷区。用’
’表示地雷格,用周围的地雷个数表示非地雷格。相邻字符之间无分隔符。
输入样例:

3 3
*??
???
?*?

输出样例:

*10
221
1*1

第一种做法

分析:(1)这个题可以用动态数组来做。开一个bool flag[maxn][maxn],然后遍历这个二维数组,扫到雷就把flag[i][j]更新为1。那么没雷的只能是0。那么每个问号格子里的就把八个方向的的雷数累加,最后输出。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1050;
bool flag[maxn][maxn];
int main(){
	memset(flag,0,sizeof(flag));
	ios::sync_with_stdio(false);
	int m,n;
	char ch;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>ch;
			if(ch=='*') flag[i][j]=1;
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(flag[i][j]==1) cout<<'*';
			else cout<<a[i+1][j+1]+a[i+1][j-1]+a[i+1][j]+a[i][j+1]+a[i][j-1]+a[i-1][j+1]+a[i-1][j]+a[i-1][j-1];
			//这就是那八个方向的和
		}
		cout<<endl;
	}
	return 0;
}

第二种做法

(2)DFS做法:搜索,找到地雷就把周围的数加起来
开两个二维数组,一个存场上的情况,一个存答案。
dfs函数主要是把八方向的数累加。注意最后要判断数组不要越界了。要不然会RE。
最后判断是不是地雷就行了,是就输出地雷,不是就把上面算过的数输出就行了。

#include<bits/stdc++.h>
using namespace std;
char a[101][101];
int ans[101][101]={0};
int n,m,i,j;
int dx[8]={1,0,-1,0,-1,1,1,-1};
int dy[8]={0,1,0,-1,-1,-1,1,1};
void dfs(int x,int y)
{
 	   int nx,ny,k;
 	   for (k=0;k<8;k++){
       	nx=x+dx[k];
       	ny=y+dy[k];
       	if (nx>=1&&nx<=n&&ny>=1&&ny<=m) ans[nx][ny]++;
   }
}
int main(){
 cin>>n>>m;//输入
 for (i=1;i<=n;i++)
    for (j=1;j<=m;j++){
        cin>>a[i][j];
        if (a[i][j]=='*') dfs(i,j);
        }
 for (i=1;i<=n;i++){
    for (j=1;j<=m;j++)
       if (a[i][j]=='*') cout<<a[i][j];
       else cout<<ans[i][j];
       cout<<endl;
    }
 return 0;
}

P1518 [USACO2.4]两只塔姆沃斯牛

两只牛逃跑到了森林里。F J 开始用他的专家技术追捕这两头牛。你的任务是模拟他们的行为(牛和 John)。

追击在 10×10 的平面网格内进行。一个格子可以是:一个障碍物,两头牛(它们总在一起),或者 Farmer John。两头牛和 Farmer John 可以在同一个格子内(当他们相遇时),但是他们都不能进入有障碍的格子。

一个格子可以是:

. 空地;
* 障碍物;
C 两头牛;
F Farmer John。

这里有一个地图的例子:

*...*.....
......*...
...*...*..
..........
...*.F....
*.....*...
...*......
..C......*
...*.*....
.*.*......

牛在地图里以固定的方式游荡。每分钟,它们可以向前移动或是转弯。如果前方无障碍(地图边沿也是障碍),它们会按照原来的方向前进一步。否则它们会用这一分钟顺时针转 90 度。 同时,它们不会离开地图。

Farmer John 深知牛的移动方法,他也这么移动。

每次(每分钟)Farmer John 和两头牛的移动是同时的。如果他们在移动的时候穿过对方,但是没有在同一格相遇,我们不认为他们相遇了。当他们在某分钟末在某格子相遇,那么追捕结束。

读入十行表示地图。每行都只包含 10 个字符,表示的含义和上面所说的相同。保证地图中只有一个 F 和一个 C。F 和 C 一开始不会处于同一个格子中。

计算 Farmer John 需要多少分钟来抓住他的牛,假设牛和 Farmer John 一开始的行动方向都是正北(即上)。 如果 John 和牛永远不会相遇,输出 0。

输入格式
输入共十行,每行 10 个字符,表示如上文描述的地图。

输出格式
输出一个数字,表示 John 需要多少时间才能抓住牛们。如果 John 无法抓住牛,则输出 0。

输入:

*...*.....
......*...
...*...*..
..........
...*.F....
*.....*...
...*......
..C......*
...*.*....
.*.*......

输出:49

分析:这个题实在太经典了。

我直接搬老刘总结的了;)

这个地图上只有100个点,FJ和牛只会面对4个方向,所以FJ只会有400个不同状态,牛也有400个不同状态,一共有160000个状态,如果超过160000分钟,如果还不相遇,就不会相遇了。因为如果某个状态已经出现过了,第二次出现后,肯定陷入一种死循环中。

#include<bits/stdc++.h>
using namespace std;
const int toocircle=1919810;//循环周期,这个周期必须大于160000 
const int dx[4]={-1,0,1,0};
const int dy[4]={0,1,0,-1};//上右下左 顺时针 
int fx,fy,cx,cy;
int dfj=0,dcs=0,ans; //FJ的方向,牛的方向,最初都是面向被,下标都是0 
char mapp[12][12];
inline void nextstep(int &x,int &y,int &d){
	x=x+dx[d],y=y+dy[d];//移动
	if(mapp[x][y]=='*'){ //回撤转弯 
		x=x-dx[d];
		y=y-dy[d];
		d=(d+1)%4;//转弯90° 
	} 
}
void init(){
	for(int i=1;i<=10;i++){
		for(int j=1;j<=10;j++){
			cin>>mapp[i][j];
			if(mapp[i][j]=='C') cx=i,cy=j;//如果找到了牛,记录牛的位置
			if(mapp[i][j]=='F') fx=i,fy=j;//如果找到了Fj,记录Fj的位置 
		}
	}
	for(int i=0;i<=11;i++){ //自动加一圈障碍,这样不用判断是否到边
		mapp[i][0]=mapp[0][i]=mapp[11][i]=mapp[i][11]='*';
		//注意看这个是矩形边界。这个一般不容易想到 
	} 
}
void work(){
	ans=0;
	for(;(fx!=cx || fy!=cy) && ans<toocircle;ans++){
		nextstep(fx,fy,dfj);//FJ走一步 
		nextstep(cx,cy,dcs);//牛走一步 
	}
	if(ans<toocircle) cout<<ans<<endl;//如果这个答案在范围以内,直接输出就好了 
	else cout<<0<<endl;//找不到 

}
int main(){
	init();
	work();
	return 0;
} 

标签:11,...,单刷题,20,地雷,格子,int,John,号洛谷题
来源: https://blog.csdn.net/qq_35684989/article/details/117083170

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有