题目:http://poj.org/problem?id=1753

这个题在開始接触的训练计划的时候做过,当时用的是DFS遍历,其机制就是把每一个棋子翻一遍。然后顺利的过了。所以也就没有深究。

省赛前一次做PC2遇到了差点儿一模一样的题,仅仅只是是把棋盘的界限由4X4改为了5X5,然后一直跑不出结果来,可是当时崔老湿那个队过了,在最后总结的时候。崔老湿就说和这个题一样,只是要枚举第一行进行优化。

我以为就是恢复第一行然后第二行以此类推,只是手推一下结果是6不是4,就知道这个有问题。

问了崔老湿,问了+才。我发现我的思路不对。应该是用DFS把第一行全部可能出现的情况枚举出来,然后再一行一行的推导。

第一次A的代码:

//DFS
#include <stdio.h>
#include <stdlib.h>
#include <string.h> int MAP[5][5];
int ans = 999999; int pd (void)
{
int i,k;
int ans = 0;
for (i = 0;i < 4;i++)
for (k = 0;k < 4;k++)
ans += MAP[i][k]; if (ans == 0 || ans == 16)
return 1; return 0;
} int fan (int x,int y)
{
MAP[x][y] = !MAP[x][y]; if (x - 1 >= 0)
MAP[x - 1][y] = !MAP[x - 1][y];
if (y - 1 >= 0)
MAP[x][y - 1] = !MAP[x][y - 1];
if (x + 1 < 4)
MAP[x + 1][y] = !MAP[x + 1][y];
if (y + 1 < 4)
MAP[x][y + 1] = !MAP[x][y + 1];
return 0;
} int dfs (int x,int y,int t)
{
if (pd ())
{
if (ans > t)
ans = t; return 0;
} if (x >= 4 || y >= 4)
return 0; int nx = (x + 1) % 4,ny = y + (x + 1) / 4; dfs (nx,ny,t);
fan (x,y); dfs (nx,ny,t + 1);
fan (x,y); return 0;
} int main()
{
int i,k; for (i = 0;i < 4;i++)
{
char s[5];
scanf ("%s",s); for (k = 0;k < 4;k++)
if (s[k] == 'b')
MAP[i][k] = 1;
else
MAP[i][k] = 0;
} dfs (0,0,0); if (ans == 999999)
puts ("Impossible");
else
printf ("%d\n",ans);
return 0;
}

用枚举的代码:

//DFS + 枚举
#include <stdio.h>
#include <stdlib.h>
#include <string.h> int MAP[5][5];
int tMAP[5][5];
int ans = 999999; int pd (int n)
{
int i;
int re = 0;
for (i = 0;i < 4;i++)
re += tMAP[3][i]; if (n == 1 && re == 0) //防止前三行为1最后一行0以及反之等的特殊情况
return 1; if (n == 2 && re == 4)
return 1; return 0;
} int fan (int x,int y)
{
tMAP[x][y] = !tMAP[x][y]; if (x - 1 >= 0)
tMAP[x - 1][y] = !tMAP[x - 1][y];
if (y - 1 >= 0)
tMAP[x][y - 1] = !tMAP[x][y - 1];
if (x + 1 < 4)
tMAP[x + 1][y] = !tMAP[x + 1][y];
if (y + 1 < 4)
tMAP[x][y + 1] = !tMAP[x][y + 1];
return 0;
} int fanM (int x,int y)
{
MAP[x][y] = !MAP[x][y]; if (x - 1 >= 0)
MAP[x - 1][y] = !MAP[x - 1][y];
if (y - 1 >= 0)
MAP[x][y - 1] = !MAP[x][y - 1];
if (x + 1 < 4)
MAP[x + 1][y] = !MAP[x + 1][y];
if (y + 1 < 4)
MAP[x][y + 1] = !MAP[x][y + 1];
return 0;
} int dfs (int x,int y,int t)
{
if (x >= 1)
{
//枚举
memcpy (tMAP,MAP,sizeof (MAP));
int tmp = t;
int i,k; for (i = 1;i < 4;i++)
{
for (k = 0;k < 4;k++)
{
if (tMAP[i - 1][k] == 1)
{
fan (i,k);
tmp++;
}
}
} if (pd (1))
ans = ans < tmp ? ans : tmp; memcpy (tMAP,MAP,sizeof (MAP));
tmp = t; for (i = 1;i < 4;i++)
{
for (k = 0;k < 4;k++)
{
if (tMAP[i - 1][k] == 0)
{
fan (i,k);
tmp++;
}
}
} if (pd (2))
ans = ans < tmp ? ans : tmp;
return 0;
}
int ny = (y + 1) % 4,nx = x + (y + 1) / 4; dfs (nx,ny,t);
fanM (x,y); dfs (nx,ny,t + 1);
fanM (x,y); return 0;
} int main()
{
int i,k; for (i = 0;i < 4;i++)
{
char s[5];
scanf ("%s",s); for (k = 0;k < 4;k++)
if (s[k] == 'b')
MAP[i][k] = 1;
else
MAP[i][k] = 0;
} dfs (0,0,0); if (ans == 999999)
puts ("Impossible");
else
printf ("%d\n",ans);
return 0;
}

其效果还是非常明显的

把全部棋子枚举,转化为仅仅枚举第一行的棋子。就是这个题优化的思路。

POJ 1753 Flip Game (DFS + 枚举)的更多相关文章

  1. POJ 1753 Flip Game DFS枚举

    看题传送门:http://poj.org/problem?id=1753 DFS枚举的应用. 基本上是参考大神的.... 学习学习.. #include<cstdio> #include& ...

  2. poj 1753 Flip Game (dfs)

    Flip Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 28805   Accepted: 12461 Descr ...

  3. POJ 1753 Flip Game【枚举】

    题目链接: http://poj.org/problem?id=1753 题意: 由白块黑块组成的4*4方格,每次换一个块的颜色,其上下左右的块也会被换成相反的颜色.问最少换多少块,使得最终方格变为全 ...

  4. poj 1753 Flip Game(暴力枚举)

    Flip Game   Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 52279   Accepted: 22018 Des ...

  5. POJ 1753 Flip Game (枚举)

    Flip Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 26492   Accepted: 11422 Descr ...

  6. 枚举 POJ 1753 Flip Game

    题目地址:http://poj.org/problem?id=1753 /* 这题几乎和POJ 2965一样,DFS函数都不用修改 只要修改一下change规则... 注意:是否初始已经ok了要先判断 ...

  7. poj 1753 Flip Game(bfs状态压缩 或 dfs枚举)

    Description Flip game squares. One side of each piece is white and the other one is black and each p ...

  8. POJ 1753. Flip Game 枚举or爆搜+位压缩,或者高斯消元法

    Flip Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 37427   Accepted: 16288 Descr ...

  9. POJ 1753 Flip Game(高斯消元+状压枚举)

    Flip Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 45691   Accepted: 19590 Descr ...

随机推荐

  1. 让Maven正确处理javac警告

    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.1:compile (default ...

  2. rpm包下载网站

    摘自http://blog.sina.com.cn/s/blog_4942055d0100031a.html rpm包下载网站 http://www.rpmfind.net http://www.rp ...

  3. 【设计模式】学习笔记13:组合模式(Composite)

    本文出自   http://blog.csdn.net/shuangde800 认识组合模式 上一篇中,我们可以用迭代器来实现遍历一个集合(数组,ArrayList, Vector, HashTabl ...

  4. 聚类算法初探(四)K-means

    最近由于工作需要,对聚类算法做了一些相关的调研.现将搜集到的资料和自己对算法的一些理解整理如下,供大家参考. 另外在算法代码方面,我也做了一些实现(包括串行和并行),欢迎感兴趣的朋友探讨和交流. 第一 ...

  5. 使用工具来提升Android开发效率

    正所谓工欲善其事,必先利其器.学习并应用优秀的轮子,能够让我们跑的更快,走的更远.这里所指的工具是广义的,泛指能帮助我们开发的东西,或者能提高我们效率的东西,包含:开发工具.监測工具.第三方代码库等. ...

  6. plaidctf2015 uncorrupt png

    代码的执行时间挺长的,好囧! 参考了https://13c5.wordpress.com/2015/04/20/plaidctf-2015-png-uncorrupt/的代码 通过这个题目,也对Png ...

  7. Flash Recovery Area空间不足导致DB不能打开或hang住处理方法

    当归档目录设置在闪回恢复区,并且闪回恢复区又满了的情况下, DB 就会无法归档而hang住或者无法打开. 这种情况下打开数据库会遇到如下错误信息: SQL> select status from ...

  8. ASP.NET中怎样才能使自己的代码运行的效率更高

    一.网页设计相关: 1,做好页面布局和内容规划,只放置合适的内容,并尽可能使页面设计的最小. 2,使用好的网页编辑器,如DW,FP,不要用VS自带的编辑器,因为它会产生很多无用的沉余代码,而且设计的界 ...

  9. Nodejs随笔(三):全局对象之global

    首先,进入node REPL: mesogene@mesogene-team:~$ node > 查看global对象,发现其他全局对象(包括Buffer.require对象)以及全局方法都包含 ...

  10. UI事件之unload、resize和scroll

    unload事件 当页面卸载或用户从当前页面换到其他页面上时,会在window上触发unload事件.根据DOM2级规范规定,unload应该在body上触发,但所有浏览器都实现了在window上触发 ...