POJ 1753 Flip Game (DFS + 枚举)
题目: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 + 枚举)的更多相关文章
- POJ 1753 Flip Game DFS枚举
看题传送门:http://poj.org/problem?id=1753 DFS枚举的应用. 基本上是参考大神的.... 学习学习.. #include<cstdio> #include& ...
- poj 1753 Flip Game (dfs)
Flip Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 28805 Accepted: 12461 Descr ...
- POJ 1753 Flip Game【枚举】
题目链接: http://poj.org/problem?id=1753 题意: 由白块黑块组成的4*4方格,每次换一个块的颜色,其上下左右的块也会被换成相反的颜色.问最少换多少块,使得最终方格变为全 ...
- poj 1753 Flip Game(暴力枚举)
Flip Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 52279 Accepted: 22018 Des ...
- POJ 1753 Flip Game (枚举)
Flip Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 26492 Accepted: 11422 Descr ...
- 枚举 POJ 1753 Flip Game
题目地址:http://poj.org/problem?id=1753 /* 这题几乎和POJ 2965一样,DFS函数都不用修改 只要修改一下change规则... 注意:是否初始已经ok了要先判断 ...
- 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 ...
- POJ 1753. Flip Game 枚举or爆搜+位压缩,或者高斯消元法
Flip Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 37427 Accepted: 16288 Descr ...
- POJ 1753 Flip Game(高斯消元+状压枚举)
Flip Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 45691 Accepted: 19590 Descr ...
随机推荐
- Thinking in C++: 第1章 为什么C++会成功(改进了C的缺点,可复用C的知识与库,执行效率相当)
本文内容摘抄自C++经典书籍:<Thinking in C++> 操作概念:OOP程序像什么 我们已经知道,用C 语言编写的过程程序就是一些数据定义和函数调用.要理解这种程序的含义,程 ...
- QT:“下载速度柱状图”的模拟实现——思路真好,会动脑筋,连我都有了启发(这个思路好像是通用的)
不知是哪个版本的迅雷,有个“下载速度柱状图”的小界面,我比较喜欢(只不过最新版本的迅雷却没了),所以决定来山寨一个.当然,这个山寨品不能下载文件,呵呵. 思路:1:将界面的背景涂成黑色2:每隔0.1秒 ...
- linux脚本之简单实例
利用脚本计算10的阶乘 简单说明一下: #!/bin/bash说明该shell使用的bash shell程序.这一句不可少for i in `seq 1 10`还可以写成for i in 1 2 3 ...
- exit()与_exit()的区别
从图中可以看出,_exit 函数的作用是:直接使进程停止运行,清除其使用的内存空间,并清除其在内核的各种数据结构:exit 函数则在这些基础上做了一些小动作,在执行退出之前还加了若干道工序.exit( ...
- hdu 1421 搬寝室(dp)
Problem Description 搬寝室是很累的,xhd深有体会.时间追述2006年7月9号,那天xhd迫于无奈要从27号楼搬到3号楼,因为10号要封楼了.看着寝室里的n件物品,xhd开始发呆, ...
- Cocoapod安装使用
近期换工作.项目中推荐使用Cocoapod,把经常使用的第三方库增加到project中,大致说一下流程,标记一下. 第一步:安装 CocoaPods是跑在Ruby的软件,安装可能须要几分钟.打开你的终 ...
- 【最大流】【HDU3572】Task Schedule
题意: 有N个事件,M台机器.事件有开始时间,持续时间,要在结束时间之前完成,问是否能完成所有事件? 非自己思考出来的 建图:把每个任务和每一天都看做一个点,添加源点和汇点.源点与每个任务之间连一条边 ...
- js 去重 字符串 [123123,123123,345435,33467,45645,343467,879,45645]
function unique(dislodgeArr) { var ret = [] var hash = {} var datasource = new Array(); var array= d ...
- C#编程打字指法练习
很惊讶昨晚写的第一篇学习笔记竟然有个评论了,只是今天还是对基础知识提不起精神,还是先看那三本书了解一下程序开发的大概流程吧. 今天不知道怎么闲逛就找到了这个网站,说是专门用于编程练习的,用google ...
- 手机不支持onchange事件
今天,微信上用input type=date来计算日期,苹果上可以,我的小米2s手机死活不触发onchange,大三星的onchange效果怎么看都是onblur.听燕哥说,这事儿,得折腾. 搞来搞去 ...