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 ...
随机推荐
- Android_listview设置每条信息的间距
Android_listview设置每条信息的间距 设置listView的item间距,可以在xml布局文件中的listView下设置xml属性: android:divider="#000 ...
- LoggingApplicationListener
org.springframework.boot:spring-boot:1.3.0.M1 spring-boot-1.3.0.M1.jar package org.springframework.b ...
- 不借助第三方jar包实现文件上传
假设实现文件上传难道非要借助第三方jar包(最经常使用的莫过于apache的commons-fileupload工具包)来实现吗?答案是否定的.以下通过样例演示在不借助第三方jar包的前提下怎样实现文 ...
- 【剑指offer】连续子数组的最大和
个開始,到第3个为止).你会不会被他忽悠住? 输入: 输入有多组数据,每组測试数据包括两行. 第一行为一个整数n(0<=n<=100000),当n=0时,输入结束.接下去的一行包括n个整数 ...
- Android使用Google推荐的联网框架Volley,让连接网络更加简单
大家好.随着技术的进步.科技的发达,非常少有应用是单机的了,大部分都须要联网訪问server,曾经我们都用 httpclient和httpurlconnection,感觉是不是非常麻烦,而Google ...
- js 推断 当页面无法回退时(history.go(-1)),关闭网页
在做一个Web项目时遇到一个需求,当页面没有前驱历史记录时(就是当前为新弹出的页面,没法做goback操作即history.go(-1)),点击返回button时直接关闭页面,否则就退回到前一页. 遇 ...
- JavaScript判断图片是否加载完成
一.load事件 <!DOCTYPE HTML><html> <head> <meta charset="utf-8"> ...
- 键盘事件之keydown keypress keyup区别
经过测试,显然事件执行的顺序是: keydown->keypress->keyup. 但是连续按一个按键的话,会一直触发:keydown keypress.直到你提起按键,会触发keyup ...
- HTML5 canvas 绘制精美的图形
HTML5 是一个新兴标准,它正在以越来越快的速度替代久经考验的 HTML4.HTML5 是一个 W3C “工作草案” — 意味着它仍然处于开发阶段 — 它包含丰富的元素和属性,它们都支持现行的 HT ...
- IIS应用程序池自动回收问题的有效解决办法
问题:Timer不能持续执行,如果长时间没有访问,就会被IIs自动回收.造成一些定时作业无法完成. 解决方式1:改用windows服务或是winform方式 解决方式2:在Application_En ...