#1474 : 拆字游戏

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

小Kui喜欢把别人的名字拆开来,比如“螺”就可以拆成“虫田糸”,小Kui的语文学的不是很好,于是她决定使用编程的方式来解决这个问题。

给出一个01矩阵,1占据的部分即为需要拆的字,如果两个1分享一条边,那么它们连通。连通具有传递性,即如果a、b连通,b、c连通,则a、c连通。

连通的一系列1被看做可以拆出的一块,现在小Kui需要输出这些拆出的块(用一个01矩阵表示,并且要求矩阵的大小尽可能的小)。

为了确保输出的顺序尽可能的和书写的顺序一致,小Kui从每个块中选出最左上角的点(最左侧的点中,最靠上的)作为代表点,然后按照代表点从左到右(若相同则按从上到下)的顺序输出所有拆出的块。

输入

输入的第一行为两个正整数N、M,表示01矩阵的大小。

接下来N行,每行M个01字符,描述一个需要拆的字。

对于40%的数据,满足1<=N,M<=10。

对于100%的数据,满足1<=N,M<=500。

输出

按照代表点从左到右(若相同则按从上到下)的顺序输出所有拆出的块。

对于每个块,先输出其大小,然后用对应的01矩阵表示这个块。

额外的样例

样例输入 样例输出
11 17
00000000000000000
00001111111100000
00000000000000000
00111111111111100
00000000100000000
00000010101110000
00000110100011000
00011100100001000
00000010100000000
00000001100000000
00000000000000000

7 13
1111111111111
0000001000000
0000001000000
0000001000000
0000001000000
0000001000000
0000011000000
3 4
0001
0011
1110
1 8
11111111
1 1
1
3 4
1110
0011
0001
样例输入
  1. 14 22
  2. 0000000000001111111100
  3. 0000000000001101101100
  4. 0000110000001111111100
  5. 0000110000001101101100
  6. 0111111110001111111100
  7. 0110110110000000000000
  8. 0110110110000011000000
  9. 0111111110001111111000
  10. 0000110000000001100000
  11. 0000110110001111111100
  12. 0111111111000111111000
  13. 0000000010001101101100
  14. 0000000000000001100000
  15. 0000000000000011100000
样例输出
  1. 10 9
  2. 000110000
  3. 000110000
  4. 111111110
  5. 110110110
  6. 110110110
  7. 111111110
  8. 000110000
  9. 000110110
  10. 111111111
  11. 000000010
  12. 5 8
  13. 11111111
  14. 11011011
  15. 11111111
  16. 11011011
  17. 11111111
  18. 8 8
  19. 00110000
  20. 11111110
  21. 00011000
  22. 11111111
  23. 01111110
  24. 11011011
  25. 00011000
  26. 00111000
思路:
本质上是一个深搜的题,不过需要记录深搜的状态,将搜到所有的非联通路径记录下来。
因为是按列的顺序,所以搜的时候优先列方向遍历。
 
 
AC代码:
  1. //
  2. // Created by SeeKHit on 2017/3/5.
  3. //
  4.  
  5. #include "iostream"
  6. #include "vector"
  7. #include "algorithm"
  8. #define MAX 505
  9. using namespace std;
  10.  
  11. char a[MAX][MAX];
  12. int di[]={,-,,};
  13. int dj[]={,,,-};
  14. int n,m;
  15. int n1=; //记录多少个块
  16.  
  17. vector<pair<int,int>> vv[*];//记录图形点的数组
  18.  
  19. void dfs(int i,int j,int id)
  20. {
  21. a[i][j]='x';
  22. vv[id].push_back(make_pair(i-,j-));
  23. int ar=;
  24. for(int ii=;ii<;ii++)
  25. {
  26. int ni=di[ii]+i,nj=dj[ii]+j;
  27. if(a[ni][nj]=='')
  28. dfs(ni,nj,id);
  29. }
  30. }
  31.  
  32. int vvv[][]; //记录字块
  33. void Print(int id)
  34. {
  35. int cow=,rol=;
  36. int maxx=,minx=1e9,maxy=,miny=1e9;
  37. for(int t=;t<vv[id].size();t++)
  38. {
  39. maxx=max(maxx,vv[id][t].first);
  40. minx=min(minx,vv[id][t].first);
  41. maxy=max(maxy,vv[id][t].second);
  42. miny=min(miny,vv[id][t].second);
  43.  
  44. int x=vv[id][t].first;
  45. int y=vv[id][t].second;
  46.  
  47. }
  48. rol=maxy-miny+;
  49. cow=maxx-minx+;
  50. cout<<cow<<" "<<rol<<endl;
  51.  
  52. for(int t=;t<vv[id].size();t++)
  53. {
  54. int x=vv[id][t].first;
  55. int y=vv[id][t].second;
  56.  
  57. vvv[x-minx][y-miny]=;
  58.  
  59. }
  60.  
  61. for(int i=;i<cow;i++)
  62. {
  63. for(int j=;j<rol;j++)
  64. {
  65. cout<<vvv[i][j];
  66. vvv[i][j]=;
  67.  
  68. }
  69. cout<<endl;
  70. }
  71. }
  72.  
  73. int main()
  74. {
  75. scanf("%d %d",&n,&m);
  76. for(int i=;i<n;i++)
  77. scanf("%s",a[i+]+);
  78.  
  79. for(int j=;j<=m;j++)
  80. for(int i=;i<=n;i++)
  81. {
  82. if(a[i][j]=='')
  83. {
  84. n1++;
  85. dfs(i,j,n1);
  86. }
  87. }
  88.  
  89. for(int i=;i<=n1;i++)
  90. {
  91. Print(i);
  92. }
  93. }
 

hiho #1474 拆字游戏(dfs,记录状态)的更多相关文章

  1. Java设计模式学习记录-状态模式

    前言 状态模式是一种行为模式,用于解决系统中复杂的对象状态转换以及各个状态下的封装等问题.状态模式是将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象的状态可以灵活多变.这样在客户端使 ...

  2. 2014 网选 广州赛区 hdu 5025 Saving Tang Monk(bfs+四维数组记录状态)

    /* 这是我做过的一道新类型的搜索题!从来没想过用四维数组记录状态! 以前做过的都是用二维的!自己的四维还是太狭隘了..... 题意:悟空救师傅 ! 在救师父之前要先把所有的钥匙找到! 每种钥匙有 k ...

  3. 哈密顿绕行世界问题(dfs+记录路径)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2181 哈密顿绕行世界问题 Time Limit: 3000/1000 MS (Java/Others) ...

  4. BFS和DFS记录路径

    DFS记录路径的意义好像不大,因为不一定是最短的,但是实现起来却很简单. #include<math.h> #include<stdio.h> #include<queu ...

  5. 历届试题 危险系数-(dfs+记录路径)

     历届试题 危险系数   问题描述 抗日战争时期,冀中平原的地道战曾发挥重要作用. 地道的多个站点间有通道连接,形成了庞大的网络.但也有隐患,当敌人发现了某个站点后,其它站点间可能因此会失去联系. 我 ...

  6. Java实现 LeetCode 529 扫雷游戏(DFS)

    529. 扫雷游戏 让我们一起来玩扫雷游戏! 给定一个代表游戏板的二维字符矩阵. 'M' 代表一个未挖出的地雷,'E' 代表一个未挖出的空方块,'B' 代表没有相邻(上,下,左,右,和所有4个对角线) ...

  7. 【hihocoder 1474】拆字游戏

    [题目链接]:http://hihocoder.com/problemset/problem/1474 [题意] [题解] 题目的意思是说,那个块在最左端先出现,就先处理那个块; 每个连通块,处理出最 ...

  8. HDU 2209 翻纸牌游戏(DFS)

    题目链接 Problem Description 有一种纸牌游戏,很有意思,给你N张纸牌,一字排开,纸牌有正反两面,开始的纸牌可能是一种乱的状态(有些朝正,有些朝反),现在你需要整理这些纸牌.但是麻烦 ...

  9. Unity游戏AI记录(2d横板为例)

    using System.Collections;using System.Collections.Generic;using UnityEngine; public class GeneralPeo ...

随机推荐

  1. ArcEngine开发_添加字段,数据删除,插入,更新细节

    一.AE 向已存在的要素类中添加字段 链接:  AE 向已存在的要素类中添加字段 在向已存在的要素类中添加字段的时候,需要用到ICLASS接口.于是,进一步的调整代码如下,问题得以解决 static ...

  2. win10切换网络位置,加入已经建好的工作网络或者家庭网络时输入密码仍然加不成功时

    为了连接办公室的共享打印机,WIN10网络需要加入已经建好的家庭组,本机WIN10已经是专用网络,但是加入家庭组输入家庭组密码后,加不进去: 经过windows错误检测,查出是网络IPV6配置关掉导致 ...

  3. java去除数组中的空值

    public String[] deleteArrayNull(String []string) { String []array = string; // 声明一个list List<Stri ...

  4. redhat 7 防火墙配置

    没有iptables 用systemctl stop firewalld

  5. PTA(Basic Level)1048.数字加密

    本题要求实现一种数字加密方法.首先固定一个加密用正整数 A,对任一正整数 B,将其每 1 位数字与 A 的对应位置上的数字进行以下运算:对奇数位,对应位的数字相加后对 13 取余--这里用 J 代表 ...

  6. 小记---------破解idea2018.3.6 转载

      一.进入idea官网选择想要下载的版本 官网版本选择页面: https://www.jetbrains.com/idea/download/other.html IntelliJ IDEA 分为两 ...

  7. Python字典推导式将cookie字符串转化为字典

    Python中的列表推导式一般是大家所熟悉的,可以极大的简洁代码:而Python中的字典推导式和列表推导式也是大同小异的 cookie: PHPSESSID=et4a33og7nbftv60j3v9m ...

  8. js获取url上的指定参数

    function getAllUrlParams(url) { // get query string from url (optional) or window var queryString = ...

  9. maven项目转换为gradle项目

    进入到项目更目录,运行 gradle init --type pom 上面的命令会根据pom文件自动生成gradle项目所需的文件和配置,然后以gradle项目重新导入即可.

  10. Ubuntu分区挂载

    创建主分区: 25G    主分区    空间起始位置    Ext4日志文件系统    / (ps:安装主要放这了,原因不明) 创建swap分区: 8192MB    逻辑分区        空间起 ...