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

简单说下题意:

给你一个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


你可能感兴趣的:(C语言,uva)