在搞这种SB模拟题之前。。。一定要先把sample算明白。。。不然会很悲剧的。。。
具体思路没什么好说的了吧,每次都找当前最大的连通块,当前没有连通块或者当前最大连通块小于2的时候(坑)终止就行了。注意题目中algorithm中的第三行的while...不是if...
get_score(key, type)函数用于找当前主颜色为key的时候的最大连通块,type为0的时候找非主色调的最大块,为1的时候找主色调的最大块。每次找完之后都release(id),即将id连通块下的点都删除,并将所有点向下或向右移动。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<set>
#define REP(i, n) for(int i=0; i<n; i++)
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 55;
int n, m, vis[maxn][maxn];
char g[maxn][maxn], tg[maxn][maxn];
char pt[6] = "BGRWY";
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
bool flag, flag1;
struct Block
{
int num, l, d, id;
}b[maxn*maxn];
bool cmp(Block a, Block b)
{
if(a.num > b.num) return true;
else if(a.num == b.num)
{
if(a.d > b.d) return true;
else if(a.d == b.d && a.l < b.l) return true;
}
return false;
}
void dfs(int x, int y, int id)
{
vis[x][y] = id; b[id].num++;
b[id].l = min(b[id].l, y);
b[id].d = max(b[id].d, x);
REP(i, 4)
{
int tx = x + dx[i], ty = y + dy[i];
if(tx < 0 || tx >= n || ty < 0 || ty >= m) continue;
if(vis[tx][ty] == -1 && g[tx][ty] == g[x][y])
dfs(tx, ty, id);
}
}
void release(int id)
{
REP(i, n) REP(j, m) if(vis[i][j] == id) g[i][j] = '.';
for(int i=n-2; i>=0; i--) REP(j, m) if(g[i][j] != '.')
{
int tx = i;
for(int ii=i+1; ii<n; ii++)
{
if(g[ii][j] != '.') break;
else tx = ii;
}
if(tx == i) continue;
g[tx][j] = g[i][j];
g[i][j] = '.';
}
int mm = m;
REP(j, mm-1)
{
flag1 = 0;
REP(i, n) if(g[i][j] != '.')
{
flag1 = 1;
break;
}
if(!flag1)
{
REP(i, n) for(int jj=j+1; jj<mm; jj++)
g[i][jj-1] = g[i][jj];
REP(i, n) g[i][mm-1] = '.';
mm--; j--;
}
}
}
int get_score(char key, bool type)
{
int cnt = 0;
CLR(vis, -1);
REP(i, n) REP(j, m) if(vis[i][j] == -1)
if((type && g[i][j]==key) || (!type && (g[i][j]!='.' && g[i][j]!=key)))
{
b[cnt].num = 0; b[cnt].id = cnt;
b[cnt].l = maxn; b[cnt].d = -1;
dfs(i, j, cnt);
cnt++;
}
sort(b, b+cnt, cmp);
if(cnt == 0 || b[0].num < 2)
{
flag = false;
return 0;
}
release(b[0].id);
return b[0].num * (b[0].num - 1);
}
int gao(char key)
{
REP(i, n) REP(j, m) g[i][j] = tg[i][j];
int ret = 0;
while(true)
{
flag = true;
while(flag) ret += get_score(key, 0);
flag = true;
ret += get_score(key, 1);
if(!flag) break;
}
return ret;
}
set<char> have;
int main()
{
scanf("%d%d", &n, &m);
REP(i, n)
{
scanf("%s", tg[i]);
REP(j, m) have.insert(tg[i][j]);
}
REP(i, 5) if(have.count(pt[i])) printf("%c: %d\n", pt[i], gao(pt[i]));
return 0;
}