题目: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. fstab 介绍

    http://forum.ubuntu.org.cn/viewtopic.php?t=58468 主要翻译自http://www.tuxfiles.org/linuxhelp/fstab.html,根 ...

  2. Monthly Expense(二分) 分类: 二分查找 2015-06-06 00:31 10人阅读 评论(0) 收藏

    Description Farmer John is an astounding accounting wizard and has realized he might run out of mone ...

  3. 【FSFA 读书笔记】Ch4 Volume Analysis & Cr 5 PC-based Partitions

    Volume Analysis 1. “卷”可以理解为从逻辑上对物理存储设备的重新编制,便于操作系统管理. (A volume is a collection of addressable secto ...

  4. 杭电oj1219 AC Me

    Tips:本题中,输入字符串之后,直接从头到尾处理一遍,调用函数判断是否是字母,不要自己写循环判断是否为字母,易超时! 不过本题中有一个疑问,自己最开始用C写的,一直是Time Limit Excee ...

  5. SoftLAyer VPN

    1,安装softlayer-VPN(即跑VPN客户端)的机器与在SoftLAyer中的HardwareHostServers or VMIServer的privateIP互通

  6. HBase 2、HBase安装与初试牛刀

    官方帮助文档:http://hbase.apache.org/book.html  PDF:http://hbase.apache.org/apache_hbase_reference_guide.p ...

  7. PHP出现Notice: unserialize() [function.unserialize]: Error at offset问题的解决方案

    有两个原因(据我所知)会导致这个问题: (1) 字符串本身的问题 (2)字符编码的问题. 你unserialize的字符串的编码和文件本身的编码不一致.将文件编码改成和字符串一样的编码.这种问题比较隐 ...

  8. OC基础2:一些基本概念

    "OC基础"这个分类的文章是我在自学Stephen G.Kochan的<Objective-C程序设计第6版>过程中的笔记. 1.字符常量是存放在单引号中的单个字符,字 ...

  9. C#中MessageBox用法总结

    我们在程序中经常会用到MessageBox. MessageBox.Show()共有21中重载方法.现将其常见用法总结如下: 1.MessageBox.Show("Hello~~~~&quo ...

  10. H面试程序(11): 判断字符串是否包含子串问题

    题目描述:                        如字符串str1为''abcdef'''                       字符串str2为'' bc''; 则字符串str1中含有 ...