codeforces 567 div2 flag

题目大意:

就是有一个棋盘,棋盘上面最多有26种颜色,相邻行的同样颜色的小格子可以组成大格子(每个大格子理解为宽度为1,长为h的小矩形),相同高度的上下相邻不同颜色的连续3个大格子可以组成一面旗,问棋盘上有多少旗。

解题思路:

由于时面向题解写的代码,这里就简单的将codeforces上的内容搬一下。

简要来说,就是暴力。这种暴力题的难点就是,我们需要枚举什么。而且这样枚举不能超复杂度,不能重复枚举。在这里有一个重要的发现就是,大旗子本身就是小旗子组成的,每个小旗子有三个属性 color1,color2,color3,l,分别代表上中下的颜色,以及每块的长度。所以我们关键是先要找到小旗子,而小旗子,我们可以通过枚举的方法得到。

对棋盘的行和列进行暴力,我们可以枚举旗子的上中下的小格子来寻找,比如我这里代码枚举的就是中格子的最上面的一个的矩形,这种中格子最上面的格子的特点就是与最上面的格子临近的颜色不一致。然后判断中格子的color和length,看这个中格子是否存在旗子。然后往列的右边走,看是否存在大矩形(大旗子)。

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef struct{
	bool nu;
	char upcolor;
	char midcolor;
	char downcolor;
	int l;
}flagInf;
int main(){
	int r,c;
	cin>>r>>c;
	char chess[r][c];
	for(int i=0;i<r;i++){
		for(int j=0;j<c;j++){
			cin>>chess[i][j];
		}
	}
	int ans=0;
	int w;
	flagInf fl;
	for (int i=1;i<r-1;i++){
		w=0;
		fl.nu=true;
		for(int j=0;j<c;j++){
		char nmidcolor=chess[i][j];
		if(chess[i-1][j]!=chess[i][j]){
			int l=1;
			int cur=1;
			for(int z=i+1;z<r;z++){
				if(chess[z][j]!=chess[i][j])break;
				l++;
			}
			//cerr<<l<<endl;
			int uplength=0;
			char nupcolor;
			for(int z=i-1;z>=0;z--){
				if(chess[z][j]== chess[i][j])break;
				if(z!=i-1){
					if(chess[z][j]!=chess[z+1][j])break;
				}
				nupcolor=chess[z][j];
				uplength++;
			}
			//cerr<<i<<" "<<j<<" "<<uplength<<endl;
			if(uplength<l){
				w=0;
				fl.nu=true;
				continue;}
			int downlength=0;
			char ndowncolor;
			for(int z=i+l;z<r;z++){
				if(chess[z][j]==chess[i][j])break;
				if(z!=i+l){
					if(chess[z][j]!=chess[z-1][j])break;
				}
				ndowncolor=chess[z][j];
				downlength++;
				
			}
			//cerr<<i<<" "<<j<<" "<<downlength<<endl;
			if(downlength<l){
				w=0;
				fl.nu=true;
				continue;}
			if(fl.nu==false){
				if(fl.upcolor==nupcolor && fl.downcolor==ndowncolor&& fl.midcolor==nmidcolor &&fl.l==l){
					w+=1;
					ans+=w;
				}else{
					w=1;
					ans+=w;
				}
				fl.upcolor=nupcolor;
				fl.downcolor=ndowncolor;
				fl.midcolor=nmidcolor;
				fl.l=l;
			}else{
				fl.nu=false;
				fl.upcolor=nupcolor;
				fl.downcolor=ndowncolor;
				fl.midcolor=nmidcolor;
				fl.l=l;
				w=1;
				ans+=w;
			}
			//cerr<<i<<" "<<j<<" "<<nupcolor<<" "<<nmidcolor<<" "<<ndowncolor<<" "<<l<<" "<<ans<<endl;
		}else{
			w=0;
			fl.nu=true;
		}
		}
	}
	cout<<ans<<endl;
	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值