您的位置:首页 > 其它

例题6-13 UVA 1103 Ancient Messages 古老象形符号

2016-02-20 12:51 363 查看
简单说下题意:

给你一个H行W列的字符矩阵,他们是压缩后的十六进制矩阵,把每一个字符变成四个二进制数后,1代表黑像素,0代表白像素,问这些像素组成的图案是题目6种的哪一种!

题意有几个需要注意的地方:

书中分析说数白洞个数!但有可能多个图案放在一起,如何分开呢,那就是上下左右不相互有公共边,斜着就不算了!

思路:

1.把他们存到int二维数组里面,1写成-1,0还是0,然后先第一遍dfs,把所有黑色图案编号1,2,3.。。。

2.直接循环扫描,记录每一个图案的边界。缩小dfs范围。

3.第二遍dfs,把不是id的变成id(因为可能有其他编号!),dfs完了,在把这一块恢复!

感觉dfs,循环这么多会超时,结果0.013s就过了!!

最后自己测试几组数据即可!

#include<cctype>
#include<cstdio>
#include<string>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
const int maxn = 500 + 10;
char str1[maxn];
int idx[205][205];
int idx2[205][205];
int pos[5000][4];
int r,c,kase;
const int INF = 1e8;
const int dxx[] = {0,0,1,-1};
const int dyy[] = {-1,1,0,0};
char rev(int num){
if (num == 1)return 'A';
else if (num == 3)return 'J';
else if (num == 5)return 'D';
else if (num == 4)return 'S';
else if (num == 0)return 'W';
else if (num == 2)return 'K';
}
void dfs(int x,int y,int id){
idx[x][y] = id;
for (int i = 0; i < 4; ++i){
int nx = x + dxx[i];
int ny = y + dyy[i];
if (nx >= 1 && nx <= r && ny >= 1 && ny <= c && idx[nx][ny]==-1)dfs(nx,ny,id);
}
return;
}
void dfs2(int x,int y,int id){
idx[x][y] = id;
for (int i = 0; i < 4; ++i){
int nx = x + dxx[i];
int ny = y + dyy[i];
if (nx >= pos[id][0]-1 && nx <= pos[id][2]+1 && ny >= pos[id][1]-1 && ny <= pos[id][3]+1 && idx[nx][ny] != id)dfs2(nx,ny,id);
}
return;
}
//void print(){
//    for (int i = 1 ;i <= r; ++i){
//        for (int k = 1; k <= c; ++k){
//            printf("%d",idx[i][k]);
//        }
//        printf("\n");
//    }
//}
int main()
{
//freopen("out.txt","w",stdout);

while(scanf("%d%d",&r,&c) == 2 && (r || c)){
memset(idx,0,sizeof(idx));
memset(idx2,0,sizeof(idx2));
for (int i = 0; i < 5000; ++i){
pos[i][0]= pos[i][1] = INF;
pos[i][2]= pos[i][3] = -INF;
}
for (int i = 1; i <= r; ++i){
scanf("%s",str1+1);
int cnt=4;
for (int j = 1; j <= c; ++j){
int id = isalpha(str1[j]) ?  str1[j]-'a'+10 : str1[j]-'0';
//cout << id << endl;
for (int k = 0; k < 4; ++k){idx[i][cnt-k]=-(id%2);idx2[i][cnt-k]=idx[i][cnt-k];id/=2;}
cnt+=4;
}
}
c*=4;
int cnt=0,sum=0;
for (int i = 1; i <= r; ++i){
for (int k = 1; k <= c; ++k){
if (idx[i][k] == -1){dfs(i,k,++cnt);++sum;}
idx2[i][k]=idx[i][k];
}
}
//print();
//  printf("sum = %d\n",sum);
for (int i = 1; i <= r; ++i){
for (int k = 1; k <= c; ++k){
if (idx[i][k]!=0){
int cnt=idx[i][k];
if (pos[cnt][0]>i)pos[cnt][0]=i;
if (pos[cnt][1]>k)pos[cnt][1]=k;
if (pos[cnt][2]<i)pos[cnt][2]=i;
if (pos[cnt][3]<k)pos[cnt][3]=k;
}
}
}
// print();
string s;
sum=0;
//print();
for (int i = 1; i <= cnt; ++i){
int si = pos[i][0],sj=pos[i][1];
sum = 0;
for (int j = si-1; j <= pos[i][2] + 1; ++j){
for (int k = sj-1; k <= pos[i][3] + 1; ++k){
//cout << si-1 << "- "<< k<<endl;
if (idx[j][k] != i){dfs2(j,k,i);++sum;}
}
}
for (int j = si-1; j <= pos[i][2] + 1; ++j){
for (int k = sj-1; k <= pos[i][3] + 1; ++k){
//cout << si-1 << "- "<< k<<endl;
idx[j][k] = idx2[j][k];
}
}
//     printf("%d\n",sum-1);
s.push_back(rev(sum-1));
}
//   print();
sort(s.begin(),s.end());
cout << "Case " << ++kase << ": " << s << endl;
}
return 0;
}
//
//3 1
//2
//5
//2
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: