开始学习ACM的习题了,从简单题开始。而事实证明,简单题真的不简单,至少对我来说,不简单。

POJ_1753这道题给我的感觉跟亚洲预选赛成都赛区的热身赛开灯关灯的题特别相似。看到这道题就后悔为什么当时没做这道题呢!

后悔完了还是回到现实,学习别人是怎么做的吧!题目我就不解释了,不会的自己找中文的翻译,百度上面可以找到的。

先把代码贴出来吧

  1. package poj.exercise_1753_AC;
  2. import java.util.Scanner;
  3. /*这个题目在枚举上也有一点小的技巧。如果要是暴力枚举的话,
  4. * 一旦棋盘到了16*16的话显然就吃不消了(一个东欧区域赛的题目)
  5. * ,实际上我们完全可以只枚举第一行的操作,之后,如果我们想把棋子
  6. * 全部翻成一种颜色的话,那么第二行的操作就是固定的了(因为第一行的
  7. * 棋子的状态对第二行棋子的翻转进行了约束,如果想把第一行的棋子变成
  8. * 白色,那么第二行中位于第一行黑色棋子下方的位置必须翻转,反之亦然),
  9. * 那么第三行、第四行的操作显然也是固定的了。
  10. */
  11. public class Main {
  12. static  int steps=0x7fffffff;
  13. //(x,y)坐标合起来就是中心点及上下左右坐标啦!
  14. static  int[] dx={0,0,0,1,-1};
  15. static  int[] dy={0,1,-1,0,0};
  16. /*
  17. * 把st以2进制表示,每四个的排,排四列,从右下为(0,0)左上为(3,3)
  18. * @param x竖坐标点
  19. * @param y横坐标点
  20. * @param st需要处理的数
  21. * @return 改变确定位置的状态,如1变成0或者0变成1
  22. * */
  23. public static int flip(int x, int y, int source){
  24. if(x >= 0 && x < 4 && y >= 0 && y < 4)
  25. source ^= 1 << (x * 4 + y);
  26. return source;
  27. }
  28. /*
  29. * @param current当前行
  30. * @param num 回合数
  31. * @param source 原数据
  32. * @param flag 标志 如果数据源当前位的状态不为flag,则翻动
  33. * */
  34. public static void dfs(int current,int num,int source,int flag){
  35. //如果最后一行已经翻完
  36. if(current==4){
  37. if(source==0xffff||source==0){
  38. //已经完成了任务
  39. steps=num<steps?num:steps;
  40. }
  41. return;
  42. }
  43. //把当前行都翻成同种颜色
  44. int x,y;
  45. for (int i = current-1,j=0; j < 4; j++) {//每行有四个,所以需要翻四次
  46. if( (((source& (1<< (i*4+j) ))>>(i*4+j)) ^ flag)==1 ){
  47. /*source& (1<< (i*4+j) )>>(i*4+j) :把source中的(i,j)的状态取出来*/
  48. for (int k = 0; k <5; k++) {//当前,上下左右都得翻动
  49. x=current+dx[k];
  50. y=j+dy[k];
  51. source=flip(x, y, source);
  52. }
  53. num++;
  54. }
  55. }
  56. //翻下一行
  57. dfs(current+1, num, source, flag);
  58. }
  59. /*
  60. * */
  61. public static int solve(int source){
  62. for (int i = 0; i < 16; i++) {
  63. int num=0,temp=source,x,y;
  64. for (int j = 0; j < 4; j++) {
  65. if((i&(1<<j))>0){
  66. for (int k = 0; k <5; k++) {//当前,上下左右都得翻动
  67. x=0+dx[k];
  68. y=j+dy[k];
  69. temp=flip(x, y, temp);
  70. }
  71. num++;
  72. }
  73. }
  74. dfs(1, num, temp, 0);
  75. dfs(1, num, temp, 1);
  76. }
  77. return steps==0x7fffffff?-1:steps;
  78. }
  79. public static void main(String[] args) {
  80. Scanner scanner=new Scanner(System.in);
  81. int source=0;
  82. String string="";
  83. for (int i = 0; i < 4; i++) {
  84. string+=scanner.nextLine().trim();
  85. }
  86. for (int i = 0; i < string.length(); i++) {
  87. source=(source<<1)+(string.substring(i, i+1).equals("b")?1:0);
  88. }
  89. if(solve(source)!=-1){
  90. System.out.println(steps);
  91. }else {
  92. System.out.println("Impossible");
  93. }
  94. }
  95. }

申明一下,这不是我自己想出来的,这段代码的C语言代码来自于:http://www.cnblogs.com/staginner/archive/2011/10/29/2228784.html

我只能说一下我对这段代码的理解了:首先,它充分运用了位运算。如果没有学好位运算的同学,这道题目真的是绝佳的学习学习机会。

其具体实现思想我觉得是这样的:首先把字符转化成int ,而且以二进制的方式操作。希望能注意:以二进制的方式操作。

看到程序开始我都不明白dx,dy是做什么用的?原来它是这样工作的:

把字符转化成相对应的0,1数字。以四个为一组存入int型内。dx,dy就是需要改变的点的上、下、左、右点的相对位置。设需要改变点的坐标为(0,0)。这样就好理解了!第二点就是solve方法中的循环16次,开始我也看不明白,后来才发现0-15变成2进制数,分别与1,10,100,1000(if(i&(1<<j))相与,则正好是0000,0001……1111,16种情况,不重不漏。这样就把一行的所有可能都枚举出来了!唉,不得不佩服这样的想法啊!

POJ_1753解答过程的理解相关推荐

  1. PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 call

    您的位置 首页 PyTorch 学习笔记系列 PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 发布: 2017年8月4日 7,195阅读 ...

  2. ie 不执行回调函时_javascript引擎执行的过程的理解--执行阶段

    一.概述 js引擎执行过程主要分为三个阶段,分别是语法分析,预编译和执行阶段,上篇文章我们介绍了语法分析和预编译阶段,那么我们先做个简单概括,如下: 1.语法分析: 分别对加载完成的代码块进行语法检验 ...

  3. javascript引擎执行的过程的理解--执行阶段

    一.概述 js引擎执行过程主要分为三个阶段,分别是语法分析,预编译和执行阶段,上篇文章我们介绍了语法分析和预编译阶段,那么我们先做个简单概括,如下: 1.语法分析: 分别对加载完成的代码块进行语法检验 ...

  4. uboot加载linux内核加载那些内容,几个地址参数及uboot加载启动内核过程的理解

    关于uBoot和Linux内核中几个地址参数及uboot加载启动内核过程的理解 uboot一般使用mkimage工具先制作一个启动映象文件来引导识别内核的,uboot源代码的tools/目录下有mki ...

  5. 高通芯片刷机过程---分析理解(启动分析故障分析)

    高通芯片刷机过程---分析理解(启动分析故障分析) 参考链接:高通芯片刷机我的分析理解(启动分析故障分析)_sishibin的博客-CSDN博客_高通firehose引导文件   高通芯片手机是市面上 ...

  6. DNS域名解析过程+通俗理解

    1.背景 我们知道,在网络体系中,标识一个主机会用到IP地址,由一连串数字组成的,这并不利于人们的记忆.正如我们不会在线下去用电话号码去认对方,而是通过名字去想起对方一样的道理.因此,我们才通过域名( ...

  7. 简述TCP三次握手和四次挥手的过程和理解

      简述TCP三次握手和四次挥手的过程和理解   在讲解之前先来熟悉一下TCP报文头部   源端口.目标端口:计算机上的进程要和其他进程通信是要通过计算机端口的, 而一个计算机端口某个时刻只能被一个进 ...

  8. c++ string 拼接_String类5个常见面试题的解答过程和原理

    作者:Anthony_tester原文:https://blog.csdn.net/u011541946/article/details/79865160 这篇来看看关于Java String类的5道 ...

  9. 通过分析一个C程序的汇编指令执行过程,理解计算机的工作。

    郑德伦 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 首先创建一个C程序的文 ...

  10. 简述linux的重要安装过程,对Linux安装过程的理解

    很多人都有安装Linux的经历,无非就是插张光盘或者USB到主机上,然后按照提示一步一步进行配置,完了重启一遍,OK.但是这个过程中,系统到底做了些什么事情呢?下面就简单地来说一说. 1. 可启动盘的 ...

最新文章

  1. 更新Oracle的Date字段
  2. Windows8.1提升权限安装程序
  3. 重置mysql密码的命令
  4. 【笔记】分离字符串中的数字、字母和汉字
  5. HttpServletRequest类用途
  6. C++工程师的Rust迁移之路
  7. kindle 4 简易电子书格式转换(txt转mobi)
  8. 博通linux网卡驱动,在64位CentOS 6 系统上安装Broadcom网卡驱动
  9. “蔚来杯“2022牛客暑期多校训练营1 J Serval and Essay(图的启发式合并)
  10. Windows客户端开发--获取系统mac地址(使用WMI)
  11. cad卸载工具_CAD安装失败都是红?
  12. CJ20N - 项目定义屏幕增强(SMOD: CNEX0006)
  13. 解决VMware 16在Win7虚拟机安装VMware Tools时报 “Windows 无法验证此驱动程序软件的发布者”问题
  14. wifite+hashcat
  15. 金仓KFS for Oracle RAC one node安装部署
  16. Linux内核中断号映射过程分析(三)
  17. 20201206英语单词学习(仅供自己记录)
  18. 答题库 php,CSS+jQuery+PHP+MySQL实现的在线答题功能
  19. QT调试的时候提示not in executable format:file format not recognized
  20. maven指定配置文件打包

热门文章

  1. 专题三——枚举、模拟、排序
  2. 狂神Reids学习笔记二
  3. Hudi on Flink 快速上手指南
  4. 问题的分析与解决(培训总结)
  5. android内存泄漏MAT,利用Android Studio、MAT对Android进行内存泄漏检测
  6. python exec函数_Python3
  7. python导入自己写的包_python的模块,包和目录的区别和自定义包的注意点
  8. mysql prefix_批量修改MySQL表前缀
  9. java对公项目_5个让人激动的Java项目
  10. h5点击按钮之后按钮消失_小程序webview跳转页面后没有返回按钮完美解决方案