ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

论小模拟5

2021-07-18 16:33:18  阅读:206  来源: 互联网

标签:论小 int 油滴 模拟 淘汰 六边形 1002 1001


可能是前几次排名太好飘了,这次却只有210分,排名掉到了第5名,第三题爆零,第四题只有10分(无解的点),机房大佬cydcyd又一次摘得桂冠,拿下315分的高分。

考砸了!

T1

给定nm列的六边形,偶数行的向右移动半格,每个六边形有一个权值.或#,求两个六边形之间包含两种权值的边的总数。

思路

正在处理(i,j)且权值为#,如果i%2==1,则与(i,j)相连的六边形有(i-1,j-1),(i-1,j),(i,j-1),(i,j+1),(i+1,j-1),(i+1,j)6种。

否则 与(i,j)相连的六边形有(i-1,j+1),(i-1,j),(i,j-1),(i,j+1),(i+1,j+1),(i+1,j)6种。

判断与之相连的六边形权值是否为.,计数。

第1行和第n行的情况把边界标为#就能解决。

代码

#include<bits/stdc++.h>
using namespace std;
int n,m,i,j,cnt;
bool f[52][52];
char c;
int main(){
	cin>>n>>m;
	for(i=1;i<=n;i++)
		for(j=1;j<=m;j++){
			cin>>c;
			if(c=='.')
				f[i][j]=1;//把字符处理成数值,方便下面计算
		}
	for(i=1;i<=n;i++)
		for(j=1;j<=m;j++){
			if(!f[i][j]){
				cnt+=f[i][j-1]+f[i][j+1]+f[i-1][j]+f[i+1][j];//i为奇或偶数公有的4种情况
				if(i%2)
					cnt+=f[i-1][j-1]+f[i+1][j-1];//奇数
				else
					cnt+=f[i-1][j+1]+f[i+1][j+1];//偶数
			}
		}
	cout<<cnt;
	return 0;
}

T2

给定n个竞选人,m个投票者,竞选分n-1轮,每轮每个投票者会将票投给他的投票者列表中未被淘汰的第1个人,每轮淘汰获票数最少的人(如有相同,淘汰序号大的人)输出每轮淘汰的人和获胜者。

思路

模拟,把每轮竞选的人的获票数算出来,把淘汰的人打上标记,每个人遍历投票列表,找到第1个未被淘汰的人投票,复杂度n^2m。考虑优化,由于淘汰的人不可能再次投票,故可以把每个人现在要投的人的编号存下来,因为编号是单调递增的,所以复杂度nm

代码

#include<bits/stdc++.h>
using namespace std;
int n,m,i,j,a[1001][1001],cnt[1001],Min,ans[1001]={INT_MAX/3},k;
bool f[1001];
int main(){
	cin>>n>>m;
	for(i=1;i<=m;i++)
		for(j=1;j<=n;j++)
			scanf("%d",&a[i][j]);
	for(i=1;i<=m;i++)
		cnt[i]=1;
	for(i=1;i<=n;i++){
		Min=0;
		for(j=1;j<=m;j++)
			ans[j]=0;
		for(j=1;j<=m;j++)
			for(cnt[j];cnt[j]<=n;cnt[j]++){//cnt[j]用于记录第j个人现在会投给谁
				if(!f[a[j][cnt[j]]]){
					ans[a[j][cnt[j]]]++;
					break;
				}
			}
		for(j=1;j<=n;j++)
			if(!f[j]&&ans[j]<=ans[Min])
				Min=j;//获取淘汰者下标
		f[Min]=1;
		printf("%d\n",Min);
	}
	return 0;
}

T3

在一个长方形框子里,最多有n个相异的点,在其中任何一个点上放一个很小的油滴,那么这个油滴会一直扩展,直到接触到其他油滴或者框子的边界。必须等一个油滴扩展完毕才能放置下一个油滴。那么应该按照怎样的顺序在这n个点上放置油滴,才能使放置完毕后所有油滴占据的总体积最大呢?(不同的油滴不会相互融合)

思路

搜索放置顺序,半径肯定不超过点跟边界的距离,而且还要保证当前点和其他点的距离,可以用圆心距来求,先用勾股定理求两点距离,再减去另一点的半径,即可求得。对这些结果求最小。

代码

T4

给定nm个格子,你在(1,1)位置,要到达(n,m),移动一次要消耗1秒,第1~n+m-2秒都有闪电劈下来,如果当前格子是导电格,将会传导给与它有连边的其他的导电格,其他的导电格也会继续传导,问要到达一共有多少种走法?

思路

先用搜索求连通块,然后类比过河卒,外层循环枚举行列坐标和,内层循环枚举行坐标,如果在同一个连通块且j<=m,则f[i][j]=f[i-1][j]+f[i][j-1]

代码

#include<bits/stdc++.h>
using namespace std;
int n,m,X[4]={1,0,-1,0},Y[4]={0,1,0,-1},color,vis[1002][1002],c[1002][1002],f[1001][1001],l;
bool a[1002][1002];
void dfs(int x,int y){
	if(!a[x][y]||vis[x][y])
		return;
	c[x][y]=color;
	vis[x][y]=1;
	for(int i=0;i<4;i++){
		int xx=x+X[i],yy=y+Y[i];
		dfs(xx,yy);
	}
}
int main(){
	int x,y,i,j;
	cin>>n>>m;
	for(i=1;i<=n;i++)
		for(j=1;j<=m;j++)
			scanf("%d",&a[i][j]);
	for(i=1;i<=n;i++)
		for(j=1;j<=m;j++){
			if(!a[i][j])
				c[i][j]=++color;
			else if(!vis[i][j]){
				++color;
				dfs(i,j);
			}	
		}
	f[1][1]=1;
	for(l=1;l<=n+m-2;l++){
		scanf("%d%d",&x,&y);
		for(i=1;i<=min(l+1,n);i++){
			j=l+2-i;
			if(j<=m&&c[i][j]!=c[x][y])       
				f[i][j]=(f[i-1][j]+f[i][j-1])%100000001;
		}
	}
	if(!f[n][m])
		printf("Poor Y!");
	else
		printf("%d",f[n][m]);
	return 0;
}

标签:论小,int,油滴,模拟,淘汰,六边形,1002,1001
来源: https://blog.csdn.net/weixin_52536621/article/details/118877652

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

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

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

ICode9版权所有