UVA1103-Ancient Messages(脑洞+dfs)

Problem UVA1103-Ancient Messages

Accept: 1176  Submit: 6103

Time Limit: 3000 mSec

Problem Description

 

 

 

 Input

 

 Output

 

 

 Sample Input

100 25 0000000000000000000000000

0000000000000000000000000

...(50 lines omitted)...

00001fe0000000000007c0000

00003fe0000000000007c0000

...(44 lines omitted)...

0000000000000000000000000

0000000000000000000000000

150 38

00000000000000000000000000000000000000

00000000000000000000000000000000000000

...(75 lines omitted)...

0000000003fffffffffffffffff00000000000

0000000003fffffffffffffffff00000000000

...(69 lines omitted)...

00000000000000000000000000000000000000

00000000000000000000000000000000000000

0 0

 

 

Sample output

Case 1: AKW

Case 2: AAAAA

 

题解:这个题重在脑洞,看出来联通块的个数与字母之间的关系的确不容易(我是没看出来)。开了脑洞之后问题就简单多了,先对最外面的白色区域dfs一下,然后就是dfs各个黑色区域,先把他们包围的联通块的范围划出来,然后计数里面的联通块个数,说的时候这划区域与计数是分开的,其实实现的时候是在一起的,划区域的时候如果碰到了白格,就停下来先对这个白格所在的联通块进行dfs,顺便记个数,区域划完了,计数也就搞定了

 

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 using namespace std;
  6 
  7 const int maxn = 200+5,maxm = 50+5;
  8 const int converse[16][4] =
  9 {
 10     {0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},
 11     {0,1,0,0},{0,1,0,1},{0,1,1,0},{0,1,1,1},
 12     {1,0,0,0},{1,0,0,1},{1,0,1,0},{1,0,1,1},
 13     {1,1,0,0},{1,1,0,1},{1,1,1,0},{1,1,1,1}
 14 };
 15 
 16 char gra[maxn][maxm];
 17 int buf[maxn][maxm<<2];
 18 int n,m,cnt;
 19 int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
 20 
 21 inline bool Judge(int x,int y){
 22     if(0<=x && 0<=y && x<n && y<m) return true;
 23     else return false;
 24 }
 25 
 26 void dfsw(int x,int y,int num){
 27     buf[x][y] = num;
 28     int xx,yy;
 29     for(int i = 0;i < 4;i++){
 30         xx = x+dir[i][0],yy = y+dir[i][1];
 31         if(Judge(xx,yy) && buf[xx][yy] == 0){
 32             dfsw(xx,yy,num);
 33         }
 34     }
 35 }
 36 
 37 void dfsn(int x,int y,int num){
 38     buf[x][y] = num;
 39     int xx,yy;
 40     for(int i = 0;i < 4;i++){
 41         xx = x+dir[i][0],yy = y+dir[i][1];
 42         if(Judge(xx,yy)){
 43             if(buf[xx][yy] == 1) dfsn(xx,yy,num);
 44             else if(buf[xx][yy] == 0){
 45                 cnt++;
 46                 dfsw(xx,yy,-1);
 47             }
 48         }
 49     }
 50 }
 51 
 52 void map_print(){
 53     for(int i = 0;i < n;i++){
 54         for(int j = 0;j < m;j++){
 55             printf("%d ",buf[i][j]);
 56         }
 57         printf("\n");
 58     }
 59 }
 60 
 61 int sum[10];
 62 char q[10] = {'W','A','K','J','S','D'};
 63 int iCase = 1;
 64 
 65 int main()
 66 {
 67     //freopen("input.txt","r",stdin);
 68     //freopen("output.txt","w",stdout);
 69     while(~scanf("%d%d",&n,&m) && (n||m)){
 70         memset(buf,0,sizeof(buf));
 71         for(int i = 1;i <= n;i++){
 72             scanf("%s",gra[i]+1);
 73             for(int j = 1;j <= (int)strlen(gra[i]+1);j++){
 74                 int y = (j-1)<<2;
 75                 if('a'<=gra[i][j] && gra[i][j]<='z'){
 76                     for(int k = 0;k < 4;k++){
 77                         buf[i][y+k+1] = converse[gra[i][j]-'a'+10][k];
 78                     }
 79                 }
 80                 else{
 81                     for(int k = 0;k < 4;k++){
 82                         buf[i][y+k+1] = converse[gra[i][j]-'0'][k];
 83                     }
 84                 }
 85             }
 86         }
 87         n = n+2,m = 4*m+2;
 88         //map_print();
 89         dfsw(0,0,-1);
 90         int flag = 2;
 91         memset(sum,0,sizeof(sum));
 92         for(int i = 0;i < n;i++){
 93             for(int j = 0;j < m;j++){
 94                 if(buf[i][j] == 1){
 95                     cnt = 0;
 96                     dfsn(i,j,flag);
 97                     flag++;
 98                     sum[cnt]++;
 99                 }
100             }
101         }
102         //map_print();
103         printf("Case %d: ",iCase++);
104         if(sum[1] != 0) for(int i = 0;i < sum[1];i++) printf("%c",'A');
105         if(sum[5] != 0) for(int i = 0;i < sum[5];i++) printf("%c",'D');
106         if(sum[3] != 0) for(int i = 0;i < sum[3];i++) printf("%c",'J');
107         if(sum[2] != 0) for(int i = 0;i < sum[2];i++) printf("%c",'K');
108         if(sum[4] != 0) for(int i = 0;i < sum[4];i++) printf("%c",'S');
109         if(sum[0] != 0) for(int i = 0;i < sum[0];i++) printf("%c",'W');
110         printf("\n");
111     }
112     return 0;
113 }

 

转载于:https://www.cnblogs.com/npugen/p/9504365.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值