gym102465I Mason‘s Mark

https://codeforces.com/gym/102465/problem/I

法国人的英语感觉都不在说人话。。。题面写得巨纠结。。。。

这题本来我写了3个函数准备分别判断ABC的。。。然后发现会不会A的中间的白色区域又有嵌套之类的情况,那么中间到底是全白还是会有嵌套或者噪音点?题意也没说清楚

但是注意到题意说一个石头必须恰好有一个mark,说明dfs出一个黑色点,只要他不是单独一个噪声点,那么必在一个字母上

所以这题那些个什么x,y按比例都不太重要了,直接按照形状算每个连通块的关键点是黑的还是白的判断这个连通块是A还是BC了

于是删掉100行代码。。。

这场锅挺大的,C有机会写的,然而我I花了很长时间,一开始没想清楚题意就上了,最后又回来跟队友确认题意,导致后面C没时间写,主要是去年队友太弱的时候,反正一直都是我上机,总是喜欢没想清楚就上,然后慢慢弄清题意和写题细节,然而今年这样做就会浪费机时。。。

#include<bits/stdc++.h>
using namespace std;

const int maxl=1010;

int n,m;
int ans[4];
char a[maxl][maxl];
bool vis[maxl][maxl];
int tx[9]={0,0,1,-1,0,1,1,-1,-1};
int ty[9]={0,1,0,0,-1,1,-1,1,-1};
struct node
{
	int x,y;
};
queue<node> q;

inline void clr(int x,int y)
{
	while(q.size()) q.pop();
	q.push(node{x,y});a[x][y]='.';
	node d;
	while(q.size())
	{
		d=q.front();q.pop();
		for(int i=1;i<=8;i++)
		{
			x=d.x+tx[i];y=d.y+ty[i];
			if(x<1 || x>n || y<1 || y>m || a[x][y]!='#')
				continue;
			a[x][y]='.';q.push(node{x,y});
		}
	}
}

inline void prework()
{
	scanf("%d%d",&m,&n);
	for(int i=1;i<=n;i++)
		scanf("%s",a[i]+1);
	clr(1,1);
}

inline int jug(int lx,int ly,int lenx,int leny)
{
	if(a[lx+lenx][ly+lenx+leny]!='#')
		return 3;
	else if(a[lx+2*lenx+2*leny][ly+lenx]!='#')
		return 1;
	else
		return 2;
}

inline void solv(int ix,int iy)
{
	int lenx=0,leny=0,ry;
	for(int j=iy;j<=m;j++)
	if(a[ix][j]=='#')
		ry=j;
	else
		break;
	for(int i=1;i<=min(n,m);i++)
	if(a[ix+i][iy+i]=='.')
	{
		lenx=i;
		break;
	}	
	leny=(ry-iy+1)-2*lenx;
	if(lenx<=0 || leny<=0) 
		return;
	ans[jug(ix,iy,lenx,leny)]++;
}

inline void mainwork()
{
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		if(a[i][j]=='#')
		{
			solv(i,j);
			clr(i,j);
		}
}

inline void print()
{
	printf("%d %d %d",ans[1],ans[2],ans[3]);
}

int main()
{
	prework();
	mainwork();
	print();
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值