1181C flag
思维深度还是不够,看了出题人的解答才会了。。。
我们预处理出一个四元组(r,c,color,len)
r,c行号,列号;
len表示宽度为1的从单元格(r,c)向下可以扩展的连续相同颜色的长度;
color表示这一段的颜色。
这些信息可以保存在一个二维pair数组中,方便后续使用。
当我们预处理出所有宽度为1的旗帜后便可以以行号为第一层循环,我们将某一块连续区间作为旗帜三要素的中间部分,那么我们只需要判断出其上方的颜色及长度是否满足条件,下方直接连接的部分是否具有与其不同的颜色以及长度是否满足条件,我们便可以知晓宽度为1的满足条件的旗帜的四元组(color1,color2,color3,len),那么如何判断宽度呢,我们只需要判断(r,c+1)是否是一个旗帜,以及他的形状和颜色是否与(r,c)的三部分相同,若是相同则宽度加1;否则宽度置为1,我们从当前列继续向后寻找新的四元组(color1,color2,color3,len),当一行内的内容全部判断完之后,进入下一行去找寻。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89#include<bits/stdc++.h> using namespace std; const int maxn=1e3+9; char mapp[maxn][maxn]; pair<char,int> p[maxn][maxn];//预处理宽度为1的每个(r,c)可以向下走的连续相同颜色的长度与颜色; typedef long long ll; //预处理宽度为1的旗帜的信息; void init(int n,int m){ for(int j=1;j<=m;++j) for(int i=1;i<=n;){ int len=1; int r=i,c=j; while(i<=n&&mapp[i][j]==mapp[i+1][j]){ ++i; ++len; } ++i; for(int k=r;k<i;++k){ p[k][c].first=mapp[r][c]; p[k][c].second=len--; } } } int n,m; //判断一列中的连续三块是否满足宽度为1的旗帜的条件; bool shu(int r,int c,int len){ if(r-len>=1&&r-len<=n&&r+len>=1&&r+len<=n&&p[r-len][c].second>=len&&p[r+len][c].second>=len){ if(p[r][c].first!=p[r+len][c].first&&p[r][c].first!=p[r-len][c].first) return 1; return 0; } return 0; } //判断相邻两列的旗帜是否颜色相同; bool yanse(int r,int c,int len){ if(c+1<=m&&p[r][c].first==p[r][c+1].first&&p[r-len][c].first==p[r-len][c+1].first&&p[r+len][c].first==p[r+len][c+1].first) return 1; return 0; } //判断相邻两列是否可以拼接为旗帜; bool heng(int r,int c,int len){ if(c+1<=m&&p[r][c+1].second==len){ if(shu(r,c+1,len)){ if(yanse(r,c,len)) return 1; return 0; } return 0; } return 0; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) scanf("%s",mapp[i]+1); memset(p,0,sizeof(p)); init(n,m); if(n<=2){ printf("0n"); return 0; } ll res=0; for(int i=2;i<n;++i){ int j=1; while(j<=m){ if(p[i][j].second&&shu(i,j,p[i][j].second)){ int r=i,c=j,len=p[i][j].second; int w=1; while(j<=m&&heng(i,j,len)){ ++j; ++w; } res+=w*(w+1LL)/2; } ++j; } } printf("%I64dn",res); return 0; }
最后
以上就是辛勤保温杯最近收集整理的关于codeforces 1181C Flag的全部内容,更多相关codeforces内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复