UVA-1103(Ancient Messages,World Finals)
点击看图
输入H行W列的字符矩阵(H<=200, W<=50)
每个字符都是16进制数字,将他们转化为二进制后产生的图形中有'1'和'0',构成上面的图形。
根据符号内部白色洞的数量来判断。
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int maxn = 1e2 * 2 + 10;
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
char pic[maxn][maxn];
int pic1[maxn][maxn], idx[maxn][maxn];
char *bin[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111"
,"1000","1001", "1010", "1011", "1100", "1101", "1110", "1111"};
char code[] = "WAKJSD";
int h, w;
void init(){
memset(idx, 0, sizeof idx);
memset(pic1, 0, sizeof pic1);
for(int i = 0; i < h; ++i){
for(int j = 0; j < w; ++j){
if(isdigit(pic[i][j]))
pic[i][j] -= '0';
else
pic[i][j] -= 'a'-10;
for(int k = 0; k < 4; ++k)
pic1[1+i][1+j*4+k] = bin[pic[i][j]][k] - '0';//在这里将原来的图形外围补一圈0,确保外围同色
}
}
}
int dfs(int r, int c, int id){
if return;
if(idx[r][c] != 0) return;
idx[r][c] = id;
for(int i = 0; i < 4; ++i){
int rr = r+dx[i], cc = c+dy[i];
if(pic[r][c] == pic[rr][cc] && (rr >= h || rr <= 0 || cc >= w || cc <= 0)
&& idx[rr][cc] != 0)
dfs(rr, cc, id);
}
}
int main(){
while(scanf("%d %d", &h, &w) == 2 && h && w){
for(int i = 0; i < h; ++i) scanf(" %s", pic[i]);
init();
h += 2;
w = w*4 + 2;
int cnt = 0;
vector<int> ccc;
for(int i = 0; i < h; ++ i){
for(int j = 0; j < w; ++j){
if(!idx[i][j]){
dfs(i,j,++cnt);
if(pic1[i][j] == 1) ccc.push_back(cnt);
}
}
}
vector<set<int> > neigh(cnt+1);
for(int i = 0; i < H; ++i){
for(int j = 0; j < W; ++j){
if(pic[i][j]){
for(int k = 0; k < 4; ++k){
int x = i + dx[k], y = j + dy[k];
if(x >= 0 && x < H && y >= 0 && y < W &&
pic[x][y] == 0 && color[x][y] != 1)
neigh[color[i][j]].insert(color[x][y]);
}
}
}
}
vector<char> ans;
for(int i = 0, sz = cc.size(); i < sz; ++i)
ans.push_back(code[neigh[cc[i]].size()]);
sort(ans.begin(),ans.end());
printf("Case %d: ",cas++);
for(int i = 0, sz = ans.size(); i < sz; ++i)
printf("%c",ans[i]);
puts("");
}
return 0;
}