题目: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. 检测android的网络链接状态

    http://www.oschina.net/question/100267_61129?sort=default&p=1#tags_nav http://www.cnblogs.com/to ...

  2. Linux命令行之逗趣无极限

    Linux命令行之逗趣无极限 . Linux"sl"命令行 尽管"sl"代表了"蒸汽机机头",但它是用来提醒那些命令行控们别把"l ...

  3. 顶尖数据挖掘开发平台(TipDM-D2)产品白皮书

          顶尖数据挖掘开发平台 (TipDM-D2)           产  品  白  皮  书 广州泰迪智能科技有限公司 版权所有 地址: 广州市经济技术开发区科学城232号 网址: http ...

  4. VRay 2.0 SP1 2.10.01 for 3ds max 9/2008/2009/2010/2011/2012 32/64位 顶渲简体中文版+英文版[中国室内设计论坛-室内人]

    VRay 2.0 SP1 2.10.01 for 3ds max 9/2008/2009/2010/2011/2012 32/64位 顶渲简体中文版+英文版[中国室内设计论坛-室内人] 对最新版本的V ...

  5. leetcode_question_104 Maximum Depth of Binary Tree

    Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...

  6. hdu4135Co-prime 容斥原理水题

    //问一个区间[a,b]与n互素的数的个数 //利用容斥原理可知 //在[a,b] 区间内对n的素数因子 //ans = 被一个数整除的数的个数 - 被两个数的最小公倍数整除的数的个数 + 被三个数的 ...

  7. (转)js prototype 详解

    转载自:http://blog.csdn.net/chaojie2009/article/details/6719353(也是转载的.鄙视一下此人转载不著名出处.) 注意:必须带着怀疑的态度去看这篇文 ...

  8. Oracle数据库按属性成绩查询

    create or replace function bb return nvarchar2as-----------自定义游标类型type class_student is record( snam ...

  9. currentStyle、getComputedStyle

    element.offsetWidth: 返回元素的宽度,包括边框和内边距. element.offsetHeight: 返回元素的高度,包括边框和内边距. currentStyle: 获取计算后的样 ...

  10. 《C++ 标准库》读书笔记 - 第二章 Introduction to C++ and the Standard Library

    1. History of the C++ Standards 1.1 History of the C++ Standards C++98 -> C++03 -> TR1 -> C ...