题意:一个n * m的棋盘,0或1,每次改变一个格子时同时改变上下左右的格子,问用最少次数将棋盘全变成0的策略。

题解:用二进制压缩第一行更改的状态,之后遍历棋盘,如果当前格子为1则改变下方的格子,记录改变次数最小的状态为ans,最后模拟一次ans状态时的策略并输出。

代码:

  1. #include<stdio.h>
  2. #include<iostream>
  3. #include<algorithm>
  4. #include<string>
  5. #include<string.h>
  6. #include<math.h>
  7. #include<limits.h>
  8. #include<time.h>
  9. #include<stdlib.h>
  10. #include<map>
  11. #include<queue>
  12. #include<set>
  13. #include<stack>
  14. #include<vector>
  15. #define LL long long
  16. using namespace std;
  17. int dir[4][2] = {1, 0, 0, -1, 0, 1, -1, 0};
  18. int n, m;
  19. void change(int MAP[20][20], int i, int j)
  20. {
  21. MAP[i][j] = !MAP[i][j];
  22. for(int k = 0; k < 4; k++)
  23. {
  24. int ti = i + dir[k][0], tj = j + dir[k][1];
  25. if(ti > -1 && tj > -1 && ti < n && tj < m)
  26. MAP[ti][tj] = !MAP[ti][tj];
  27. }
  28. }
  29. int solve(int Map[20][20], int cse)
  30. {
  31. int MAP[20][20];
  32. memcpy(MAP, Map, sizeof MAP);
  33. int res = 0;
  34. int tmp = 0;
  35. while(cse)
  36. {
  37. if(cse & 1)
  38. {
  39. change(MAP, 0, tmp);
  40. res++;
  41. }
  42. tmp++;
  43. cse >>= 1;
  44. }
  45. for(int i = 0; i < n - 1; i++)
  46. {
  47. for(int j = 0; j < m; j++)
  48. {
  49. if(MAP[i][j])
  50. {
  51. change(MAP, i + 1, j);
  52. res++;
  53. }
  54. }
  55. }
  56. for(int i = 0; i < m; i++)
  57. if(MAP[n - 1][i])
  58. return -1;
  59. return res;
  60. }
  61. int main()
  62. {
  63. while(~scanf("%d%d", &n, &m))
  64. {
  65. int MAP[20][20];
  66. for(int i = 0; i < n; i++)
  67. for(int j = 0; j < m; j++)
  68. scanf("%d", &MAP[i][j]);
  69. int cse = 1 << m;
  70. int minn = 10000;
  71. int ans = 0;
  72. for(int i = 0; i < cse; i++)
  73. {
  74. int res = solve(MAP, i);
  75. if(res != -1 && res < minn)
  76. {
  77. minn = res;
  78. ans = i;
  79. }
  80. }
  81. if(minn == 10000)
  82. {
  83. puts("IMPOSSIBLE");
  84. continue;
  85. }
  86. int prt[20][20] = {0};
  87. int tmp = 0;
  88. while(ans)
  89. {
  90. if(ans & 1)
  91. {
  92. change(MAP, 0, tmp);
  93. prt[0][tmp] = 1;
  94. }
  95. tmp++;
  96. ans >>= 1;
  97. }
  98. for(int i = 0; i < n - 1; i++)
  99. {
  100. for(int j = 0; j < m; j++)
  101. {
  102. if(MAP[i][j])
  103. {
  104. change(MAP, i + 1, j);
  105. prt[i + 1][j] = 1;
  106. }
  107. }
  108. }
  109. for(int i = 0; i < n; i++)
  110. {
  111. for(int j = 0; j < m; j++)
  112. {
  113. if(j)
  114. printf(" ");
  115. printf("%d", prt[i][j]);
  116. }
  117. puts("");
  118. }
  119. }
  120. return 0;
  121. }

poj 3279 Fliptile的更多相关文章

  1. POJ 3279 Fliptile(翻格子)

    POJ 3279 Fliptile(翻格子) Time Limit: 2000MS    Memory Limit: 65536K Description - 题目描述 Farmer John kno ...

  2. POJ.3279 Fliptile (搜索+二进制枚举+开关问题)

    POJ.3279 Fliptile (搜索+二进制枚举+开关问题) 题意分析 题意大概就是给出一个map,由01组成,每次可以选取按其中某一个位置,按此位置之后,此位置及其直接相连(上下左右)的位置( ...

  3. 状态压缩+枚举 POJ 3279 Fliptile

    题目传送门 /* 题意:问最少翻转几次使得棋子都变白,输出翻转的位置 状态压缩+枚举:和之前UVA_11464差不多,枚举第一行,可以从上一行的状态知道当前是否必须翻转 */ #include < ...

  4. POJ 3279(Fliptile)题解

    以防万一,题目原文和链接均附在文末.那么先是题目分析: [一句话题意] 给定长宽的黑白棋棋盘摆满棋子,每次操作可以反转一个位置和其上下左右共五个位置的棋子的颜色,求要使用最少翻转次数将所有棋子反转为黑 ...

  5. poj 3279 Fliptile (简单搜索)

    Fliptile Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16558   Accepted: 6056 Descrip ...

  6. 【POJ 3279 Fliptile】开关问题,模拟

    题目链接:http://poj.org/problem?id=3279 题意:给定一个n*m的坐标方格,每个位置为黑色或白色.现有如下翻转规则:每翻转一个位置的颜色,与其四连通的位置都会被翻转,但注意 ...

  7. POJ 3279 Fliptile[二进制状压DP]

    题目链接[http://poj.org/problem?id=3279] 题意:给出一个大小为M*N(1 ≤ M ≤ 15; 1 ≤ N ≤ 15) 的图,图中每个格子代表一个灯泡,mp[i][j] ...

  8. POJ 3279 - Fliptile - [状压+暴力枚举]

    题目链接:http://poj.org/problem?id=3279 Sample Input 4 4 1 0 0 1 0 1 1 0 0 1 1 0 1 0 0 1 Sample Output 0 ...

  9. POJ - 3279 Fliptile (枚举)

    http://poj.org/problem?id=3279 题意 一个m*n的01矩阵,每次翻转(x,y),那么它上下左右以及本身就会0变1,1变0,问把矩阵变成全0的,最小需要点击多少步,并输出最 ...

  10. poj 3279 Fliptile(二进制)

    http://poj.org/problem?id=3279 在n*N的矩阵上,0代表白色,1代表黑色,每次选取一个点可以其颜色换过来,即白色变成黑色,黑色变成白色,而且其上下左右的点颜色也要交换,求 ...

随机推荐

  1. Webx常用接口

    最近在学Webx框架, 在了解webx的工作流程后, 必须要会使用自带的接口和类 常用的 Navigator  这个接口中只有两种类型的方法, 及重定向与转发, 一般用在screen包下的类(注意:s ...

  2. selenium + python网页自动化测试环境搭建

    1.python的安装 ,这个不解释,exe文件运行安装即可,既然你选择python,相信你是熟悉python的,我安装目录C:\Python27 2.setuptools 的安装也非常简单,同样是e ...

  3. ios9新特性概述

    1.iPad的分屏功能很重要. 开发者对iPad的分屏功能感到兴奋,并认为其对苹果未来非常重要.电子邮件信息应用Hop创始人艾瑞兹·皮洛索夫(Erez Pilosof)认为,如果苹果如传闻中那样决定推 ...

  4. NOSQL Mongo入门学习笔记 - MongoDB的安装(一)

    手上的工作不是很忙,所以来学习学习很久就像接触的MongoDb,无奈前段时间工作时间都比较多.记录在这里供以后参考 环境: Centos 7 64位 开始: 1. 在官网下载Mongo : wget  ...

  5. easyui DateTimeBox 取值

    $('#dt').datetimebox('getValue')

  6. EF+lambda表达式 实现LIKE模糊查询

    s => s.XianWID.StartsWith(str) 匹配以str开头的 s => s.XianWID.EndsWith(str) 匹配以str结尾的 s => s.Xian ...

  7. DevSecOps 实施篇!系列(二)

    想在自己公司建立 DevSecOps 计划?没问题,企业规模无论大小,都可轻松实现.这里有5个基本的 DevSecOps 原则可以帮助你启动.当然,如果你对 DevSecOps 还不太熟悉,不妨先看看 ...

  8. C++智能指针(auto_ptr)详解

    智能指针(auto_ptr) 这个名字听起来很酷是不是?其实auto_ptr 只是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势,但也有其局限.本文总结的8个问题足 ...

  9. 一张图让你看懂锻压、CNC、压铸、冲压四类工艺!

    (锻压+CNC+阳极.CNC+阳极.压铸+阳极.冲压+阳极手机外壳比较) 上图为一张雷达图,该图比较直观形象地描述了4大手机外壳工艺在6个维度(加工成本.CNC用量.加工周期.成品率.可设计性.外观质 ...

  10. Android:控件布局(线性布局)LinearLayout

    LinearLayout是线性布局控件:要么横向排布,要么竖向排布 决定性属性:必须有的! android:orientation:vertical (垂直方向) .horizontal(水平方向) ...