zoukankan      html  css  js  c++  java
  • Mine Number(搜索,暴力) ACM省赛第三届 G

    Mine Number

    Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^

    题目描述

    Every one once played the game called Mine Sweeping, here I change the rule. You are given an n*m map, every element is a '*' representing a mine, or a '.' representing any other thing. If I ask you what's the total number of mines around (i, j), you should check (i, j)'s up, down, left, right and also itself (if overstep the boundary, ignore it), if that position is a '*', you should add one to the total number of (i, j), and here I call the number Mine Number. For example, if the map is "..**.. ", we can get the Mine Number as "012210" easily, but here is the question, if I give you the Mine Number, can you tell me the original map?

    输入

    The input consists of multiple test cases.
    The first line contains a number T, representing the number of test cases.
    Then T lines follow. For each case, the first line contains two numbers n and m (1<=n, m<=20).representing the lines and rows. Then following n lines, each line contain m numbers each number represents the Mine Number.

    输出

    For each case, please print the case number (beginning with 1) and the original map which you reverted. The data guarantee there is only one result.

    示例输入

    2
    7 11
    10010100101
    21223221222
    32354532323
    32355532323
    31235321333
    21022201333
    10001000111
    5 6
    001110
    013431
    014541
    013431
    001110
    

    示例输出

    Case 1:
    ...........
    *..*.*..*.*
    *.*****.*.*
    *.*****.*.*
    *..***..*.*
    *...*...***
    ...........
    Case 2:
    ......
    ..***.
    ..***.
    ..***.
    ......
    

    提示

     

    来源

    2012年"浪潮杯"山东省第三届ACM大学生程序设计竞赛

    饭稀

     赛题重现是遇到此题,比赛是觉得挺麻烦,虽然有了思路,但并没有拿出时间来做。比赛过后,做了一下,代码还是比较容易写的,只是一直WA,自认为明明已经完美的代码就是不给过,最后发现一个让我想撞墙的问题,输出的地图中没有空格,我的输出即使在美观,亦不会AC的。
    正确答案是这样的:
    ...........
    *..*.*..*.*
    *.*****.*.*
    *.*****.*.*
    *..***..*.*
    *...*...***
    ...........
     
    而我的答案是这样滴:
    . . . . . . . . . . .
    * . . * . * . . * . *
    * . * * * * * . * . *
    * . * * * * * . * . *
    * . . * * * . . * . *
    * . . . * . . . * * *
    . . . . . . . . . . .

    懒得吐槽了,讲一下这道题吧,就是类似扫雷的规则,相信大家都比较熟悉扫雷,只是题中矩阵的数字表示上下左右和中(就是数字所在位置)五个位置中雷的个数。给出要求输入数字矩阵输出唯一确定的符合数字矩阵的图形矩阵'*'表示雷,'.'表示安全。

    看似题目要求从数字矩阵推出图形矩阵,我们亦可以认为是要收缩符合已知数字矩阵的图形矩阵,矩阵的每个点只有两种状态(. or *),用搜索实现起来便不是很难。

    注意:输入数字数组时要用字符形式存入字符数组中。

    货不多说,下面看代码

      1 #include <iostream>
      2 #include <string.h>
      3 #include <stdio.h>
      4 using namespace std;
      5 char mapp[25][25];
      6 char num[25][25];
      7 int n,m,dx[5]={0,-1,1,0},
      8         dy[5]={1,0,0,-1};
      9 bool ispos;
     10 bool isout(int x,int y)//判断是否出界
     11 {
     12     if( x<0||x>=m)
     13         return 0;
     14     if(y<0||y>=n)
     15         return 0;
     16     return 1;
     17 }
     18 void print(void)//输出字符数组
     19 {
     20     int i,j;
     21     for(i=0; i<m; ++i)
     22     {
     23         for(j=0; j<n; ++j)
     24             printf("%c ",mapp[i][j]);
     25         printf("
    ");
     26     }
     27 }
     28 /*void printn(void)
     29 {
     30     int i,j;
     31     for(i=0; i<m; ++i)
     32     {
     33         for(j=0; j<n; ++j)
     34             printf("%c ",num[i][j]);
     35         printf("
    ");
     36     }
     37 }*/
     38 int  prints()//判断最后一行是否全为零
     39 {
     40     int j;
     41     for(j=0; j<n; ++j)
     42         if(num[m-1][j]!='0')
     43             return 0;
     44     return 1;
     45 }
     46 void dfs(int x,int y)
     47 {
     48    // cout<<x<<' '<<y<<endl;
     49    // cout<<"--------------"<<endl;
     50    // printn();
     51    // print();
     52     if(ispos)
     53         return;
     54     if(x==m&&y==0)
     55     {
     56         if(prints())
     57         {
     58             ispos=true;
     59             print();
     60         }
     61         return;
     62     }
     63     int xx,yy,k,falg=1;
     64     for(k=0;k<=4;++k)//判断四周是否有0,
     65     {
     66         xx=x+dx[k];
     67         yy=y+dy[k];
     68         if( isout(xx,yy) && num[xx][yy]=='0' )
     69         {
     70             falg=0;//标记周围有0,不能不为'*'
     71             break;
     72         }
     73     }
     74 
     75     if(falg)//没有标记,则可以放地雷
     76     {
     77         if(isout(x-1,y)&&num[x-1][y]!='1')//若上方不唯1,则前面填错,需回溯
     78             return;
     79         mapp[x][y]='*';
     80         for(k=0;k<=4;++k)//若放地雷,周围标记地雷数-1
     81         {
     82             xx=x+dx[k];
     83             yy=y+dy[k];
     84             if( isout(xx,yy))
     85                     num[xx][yy]--;
     86         }
     87         if(y==n-1)
     88             dfs(x+1,0);
     89         else
     90             dfs(x,y+1);
     91         for(k=0;k<=4;++k)//周围标记地雷数+1恢复
     92         {
     93             xx=x+dx[k];
     94             yy=y+dy[k];
     95             if(isout(xx,yy))
     96                 num[xx][yy]++;
     97         }
     98     }
     99      mapp[x][y]='.';
    100      if(isout(x-1,y)&&num[x-1][y]!='0')//若上方不唯0,则前面填错,需回溯
    101             return;
    102   if(y==n-1&&!ispos)
    103         dfs(x+1,0);
    104     else if(!ispos)
    105         dfs(x,y+1);
    106 }
    107 int main()
    108 {
    109     int i,test,t_num;
    110     cin>>test;
    111     for(t_num=1;t_num<=test;++t_num)
    112     {
    113         cin>>m>>n;
    114         for(i=0;i<m;++i)
    115             scanf("%s",num[i]);
    116         printf("Case %d:
    ",t_num);
    117         ispos=0;
    118         dfs(0,0);
    119     }
    120     return 0;
    121 }
  • 相关阅读:
    codeforces 1C(几何题)
    poj 1015 Jury Compromise
    poj 1466 计算直线的交点数
    poj 1228 凸包第一题
    2012 MUTC 3 总结
    用优先队列优化Dij的一个代码
    有关排序时,上移,下移的处理思路
    有关缓存的思考
    python备份文件2 分类: python 20130315 15:16 233人阅读 评论(0) 收藏
    lambda表达式使用方法详解 分类: python 20130315 10:58 396人阅读 评论(0) 收藏
  • 原文地址:https://www.cnblogs.com/vivider/p/3695938.html
Copyright © 2011-2022 走看看