题目链接:http://poj.org/problem?id=2965

题解:自己想到的方法是枚举搜索,结果用bfs和dfs写都超时了。网上拿别人的代码试一下只是刚好不超时的,如果自己的代码在某些方面不够优化,那超时很正常。看来这题用dfs和bfs都不是好办法。 然后又看到比较厉害的技巧:“可知翻偶数次等于没翻,即没有翻的必要,翻奇数次的结果与翻一次的结果一样“”。有了这个重要结论,那么可以具体操作了:设一个二维数组以记录每个的翻转次数。对于每个‘+’,都翻转其所在的行列(注意‘+’只翻一次),然后更新翻转次数。最后统计翻转次数为奇数的,即为实际需要翻转的。(为什么我没想到这种方法。需要仔细体会这种思维)

代码如下:

  1. #include<stdio.h>//poj2965
  2. #include<string.h>
  3. int main()
  4. {
  5. int a[][],sum;
  6. char map[][];//map开一维已足够
  7. memset(a,,sizeof(a));
  8. for(int i = ; i<; i++)
  9. {
  10. scanf("%s",map[i]);
  11. for(int j = ; j<; j++)
  12. {
  13. if(map[i][j]=='+')
  14. {
  15. a[i][j]--;//‘+’在下面的步骤中翻了两次,要减少一次
  16. for(int k = ; k<; k++)
  17. {
  18. a[k][j]++;
  19. a[i][k]++;
  20. }
  21. }
  22. }
  23. }
  24. sum = ;
  25. for(int i = ; i<; i++)
  26. for(int j = ; j<; j++)
  27. {
  28. if(a[i][j]%) sum++;
  29. }
  30. printf("%d\n",sum);
  31.  
  32. for(int i = ; i<; i++)
  33. for(int j = ; j<; j++)
  34. {
  35. if(a[i][j]%)
  36. printf("%d %d\n",i+,j+);
  37. }
  38. }

对了,附上自己wa了的dfs和bfs;

dfs:

  1. #include<cstdio>//poj 2965dfs 超时未过
  2. #include<cstring>
  3. #define MIN(a,b) (a<b?a:b)
  4.  
  5. int a[],ans[];
  6.  
  7. int get()
  8. {
  9. for(int i = ; i<; i++)
  10. if(a[i]) return ;
  11. return ;
  12. }
  13.  
  14. void flip(int loc)
  15. {
  16. int x = loc/, y = loc%;
  17. a[loc] = !a[loc];
  18. for(int k = ; k<; k++)
  19. a[x*+k] = !a[x*+k];
  20. for(int k = ; k<; k++)
  21. a[k*+y] = !a[k*+y];
  22. }
  23.  
  24. int dfs(int loc,int step,int tar)
  25. {
  26. if(loc>) return ;
  27.  
  28. if(step==tar && get())
  29. return ;
  30.  
  31. else
  32. {
  33. flip(loc);
  34. ans[step] = loc;
  35. if(dfs(loc+,step+,tar)) return ;
  36. flip(loc);
  37.  
  38. if(dfs(loc+,step,tar)) return ;
  39.  
  40. }
  41. return ;
  42. }
  43.  
  44. int main()
  45. {
  46. int t;
  47. char s[];
  48.  
  49. memset(ans,-,sizeof(ans));
  50. for(int i = ; i<; i++)
  51. {
  52. scanf("%s",s);
  53. for(int j = ; j<; j++)
  54. {
  55. if(s[j]=='+') a[i*+j] = ;
  56. else a[i*+j] = ;
  57. }
  58. }
  59. int i;
  60. for(i = ; i<=; i++)
  61. {
  62. if(dfs(,,i)) break;
  63. }
  64. printf("%d\n",i);
  65. for(int k = ; k<i; k++)
  66. {
  67. if(ans[k]!=-)
  68. printf("%d %d\n",ans[k]/+, ans[k]%+);
  69. }
  70.  
  71. return ;
  72. }

bfs:(bfs的队列可能不够大,溢出。用stl的话又怎么记录路径呢?)

  1. #include<cstdio>//poj 2965 bfs 未过
  2. #include<cstring>
  3. #include<queue>
  4.  
  5. using namespace std;
  6.  
  7. int ss,vis[],pre[];
  8. struct node
  9. {
  10. int status, step,loc;
  11. };
  12. node q[];
  13.  
  14. void calcul( node *next,int i)
  15. {
  16. if(next->status&(<<i)) next->status -= (<<i);
  17. else next->status += (<<i);
  18. }
  19.  
  20. void turn (node *next,int i)
  21. {
  22. calcul(next,i);
  23. int xi = i/, yi = i%;
  24. for(int k = ; k<; k++)
  25. calcul(next,xi*+k);
  26. for(int k = ; k<; k++)
  27. calcul(next,k*+yi);
  28. }
  29.  
  30. int bfs()
  31. {
  32. int front = , rear = ;
  33. q[front].status = ss, q[front].step = ;
  34. vis[q[front].status] = ;
  35. if(q[front].status==)
  36. return front;
  37. memset(vis,,sizeof(vis));
  38. memset(pre,,sizeof(pre));
  39. while(front<rear)
  40. {
  41. for(int i = ; i<; i++)
  42. {
  43. q[rear].status = q[front].status;
  44. turn(&q[rear],i);
  45. if(vis[q[rear].status]) continue;
  46.  
  47. q[rear].loc = i;
  48. q[rear].step = q[front].step + ;
  49. pre[rear] = front;
  50. vis[q[rear].status] = ;
  51.  
  52. if(q[rear].status==) return rear;
  53. rear++;
  54. }
  55. front++;
  56. }
  57. return -;
  58. }
  59.  
  60. void pri_path(int rear)
  61. {
  62. if(q[rear].step>) pri_path(pre[rear]);
  63. printf("%d %d\n",q[rear].loc/+, q[rear].loc%+);
  64. }
  65.  
  66. int main()
  67. {
  68. int t;
  69. char s[];
  70. ss = ;
  71.  
  72. for(int i = ; i<; i++)
  73. {
  74. scanf("%s",s);
  75. for(int j = ; j<; j++)
  76. {
  77. if(s[j]=='+') ss += <<(i*+j);
  78. }
  79. }
  80. int rear = bfs();
  81. printf("%d\n",q[rear].step);
  82.  
  83. pri_path(rear);
  84. return ;
  85. }

poj2965 The Pilots Brothers' refrigerator —— 技巧性的更多相关文章

  1. POJ2965——The Pilots Brothers' refrigerator

    The Pilots Brothers' refrigerator Description The game “The Pilots Brothers: following the stripy el ...

  2. [POJ2965]The Pilots Brothers' refrigerator (搜索/位运算)

    题意 游戏“The Pilots Brothers:跟随有条纹的大象”有一个玩家需要打开冰箱的任务. 冰箱门上有16个把手.每个手柄可以处于以下两种状态之一:打开或关闭.只有当所有把手都打开时,冰箱才 ...

  3. poj2965 The Pilots Brothers' refrigerator

    题目链接:http://poj.org/problem?id=2965 分析:1.这道题和之前做的poj1753题目差不多,常规思路也差不多,但是除了要输出最少步数外,还要输出路径.做这道题的时候在怎 ...

  4. POJ 2965 The Pilots Brothers' refrigerator 暴力 难度:1

    The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16868 ...

  5. POJ 2965. The Pilots Brothers' refrigerator 枚举or爆搜or分治

    The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22286 ...

  6. POJ2965The Pilots Brothers' refrigerator(枚举+DFS)

    The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22057 ...

  7. The Pilots Brothers' refrigerator(dfs)

    The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 19718 ...

  8. 枚举 POJ 2965 The Pilots Brothers' refrigerator

    题目地址:http://poj.org/problem?id=2965 /* 题意:4*4的矩形,改变任意点,把所有'+'变成'-',,每一次同行同列的都会反转,求最小步数,并打印方案 DFS:把'+ ...

  9. The Pilots Brothers' refrigerator 分类: POJ 2015-06-15 19:34 12人阅读 评论(0) 收藏

    The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20304 ...

随机推荐

  1. JAVA Eclipse创建Android程序界面不显示怎么办

    一般是由于你创建的Android应用程序版本太高导致的,请设置4或以下版本,对于已有的项目,可以在属性-Android中修改目标生成的版本号                               ...

  2. 每天学点Python之bytes

    每天学点Python之bytes Python中的字节码用b'xxx'的形式表示.x能够用字符表示,也能够用ASCII编码形式\xnn表示.nn从00-ff(十六进制)共256种字符. 基本操作 以下 ...

  3. js 中文校验并过滤掉中文

      js中文校验并过滤掉中文 CreateTime--2017年9月6日09:10:19 Author:Marydon 思路: 1.判断字符串中是否包含中文: 2.存在中文时,过滤掉. 举例: var ...

  4. Sql 复习3之存储管理

    一.事务管理 单个工作单元称为事务,我们将若干条sql命令组合在一起,形成存储过程.触发器等,利用存储过程和触发器可以进行事务管理. 二.编程基础介绍 主要有:函数.程序设计语句等. 程序设计语句: ...

  5. Web安全系列(二):XSS 攻击进阶(初探 XSS Payload)

    什么是 XSS Payload 上一章我谈到了 XSS 攻击的几种分类以及形成的攻击的原理,并举了一些浅显的例子,接下来,我就阐述什么叫做 XSS Payload 以及从攻击者的角度来初探 XSS 攻 ...

  6. C# 嵌入dll 动软代码生成器基础使用 系统缓存全解析 .NET开发中的事务处理大比拼 C#之数据类型学习 【基于EF Core的Code First模式的DotNetCore快速开发框架】完成对DB First代码生成的支持 基于EF Core的Code First模式的DotNetCore快速开发框架 【懒人有道】在asp.net core中实现程序集注入

    C# 嵌入dll   在很多时候我们在生成C#exe文件时,如果在工程里调用了dll文件时,那么如果不加以处理的话在生成的exe文件运行时需要连同这个dll一起转移,相比于一个单独干净的exe,这种形 ...

  7. HBase——完全分布

    实际上,在真实环境中你需要使用完全分布配置完整测试HBase.在一个分布式配置中,集群有多个节点,每个节点运行一个或多个HBase守护进程.其中包括主Master和备份Master实例,多个Zooke ...

  8. 利用GROUP_CONCAT函数把相同信息的合并到同一个字段中

    SELECT a.*,GROUP_CONCAT(b.pri_name) FROM sh_role a LEFT JOIN sh_privilege b ON FIND_IN_SET(b.id,a.pr ...

  9. Unity编辑器扩展之RequireComponent等详解

    RequireComponent的使用: 当你添加的一个用了RequireComponent组件的脚本,需要的组件将会自动被添加到game object(游戏物体).这个可以有效的避免组装错误.举个例 ...

  10. 微信小程序页面布局之弹性布局-Flex介绍

    布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现. 2009年,W3C 提出了一种新 ...