POJ--1753--Flip Game【DFS】

链接:http://poj.org/problem?id=1753

题意:一个4*4的方格,有白棋或者黑棋,每次操作是一个位置的颜色翻转,即白变黑、黑变白,并且与它相邻的四个位置的颜色也都跟着改变,问最少要变化多少次才能使所有棋子都是白色或者都是黑色。

思路:不难看出一个棋子翻偶数次和不翻的效果是一样的,并且如果选定了一些棋子翻,翻的顺序对最后的结果是没有影响的,所以可以用DFS去枚举每个棋子的状态:翻或不翻,最多2^16的复杂度就能求出,65536次。

不过我WA了一发,因为每次我在dfs最后一个点的时候,翻完牌还没有判断就退出函数了,因为我写的判断条件是在下一次dfs翻牌之前判断,而最后一个点因为边界问题不会进入下一次dfs,所以再加个单独的判断,就过了

#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 810
#define eps 1e-7
#define INF 0x7FFFFFFF
typedef long long ll;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

char mapp[10][10];
int mp[10][10];
int ans;
bool check(){
    int i,j;
    for(i=0;i<4;i++){
        for(j=0;j<4;j++){
            if(mp[i][j]!=mp[0][0])  return false;
        }
    }
    return true;
}
void flip(int x,int y){
    if(x+1<4)   mp[x+1][y] = !mp[x+1][y];
    if(x-1>=0)  mp[x-1][y] = !mp[x-1][y];
    if(y+1<4)   mp[x][y+1] = !mp[x][y+1];
    if(y-1>=0)  mp[x][y-1] = !mp[x][y-1];
    mp[x][y] = !mp[x][y];
}
void dfs(int x,int y,int step){
    if(step>16) return ;
    int i, j;
    bool flag = check();
    if(flag){
        if(step<ans)    ans = step;
        return ;
    }
    flip(x,y);
    if(y+1<4)   dfs(x,y+1,step+1);
    else if(x+1<4)  dfs(x+1,0,step+1);
    else{
        if(check()){
            if(step+1<ans)    ans = step+1;
        }
    }
    flip(x,y);
    if(y+1<4)   dfs(x,y+1,step);
    else if(x+1<4)  dfs(x+1,0,step);
    else{
        if(check()){
            if(step<ans)    ans = step;
            return ;
        }
    }
}
int main(){
    int i,j;
    bool flag ;
    ans = 20;
    for(i=0;i<4;i++){
        scanf("%s",mapp[i]);
        for(j=0;j<4;j++){
            if(mapp[i][j]=='b') mp[i][j] = 1;
        }
    }
    flag = check();
    if(flag)    puts("0");
    else{
        dfs(0,0,0);
        if(ans<20)  cout<<ans<<endl;
        else    cout<<"Impossible"<<endl;
    }
    return 0;
}

POJ--1753--Flip Game【DFS】

时间: 2024-08-01 21:29:50

POJ--1753--Flip Game【DFS】的相关文章

poj 1321 棋盘问题 【DFS】

题意:... 策略:深搜. 仔细分析我们发现,我们只需要对列进行标记,对于行我们考虑放棋子还是不放就行了. 代码: #include<stdio.h> #include<string.h> char s[10][10]; int n, m; int vis[10]; int ans; void dfs(int cur, int step) { if(step == m){ ans ++; return; } if(cur > n-1) return ; int i, j; f

POJ 1753 Flip Game(dfs+枚举)

POJ 1753 题意: 输入一个4*4的图像,由黑白两色组成,定义一种操作为:改变某个格子内小球的颜色(黑变白,白变黑),同时其上下左右的格子内小球也将变色.求最少多少次操作能使之成为纯色图案. 思路: 对一个格子操作偶数次等于没有操作,操作奇数次等于操作一次,所以答案在0~16以及impossible之间. 从n=0开始枚举n次操作可能的组成情况,即操作哪几个格子,若某种组合能变图案为纯色则停止. 由于总组合数达到2^16,故枚举组合情况可以用dfs来进行回溯枚举. //还有一种方法是位运算

POJ 1564--Sum It Up【DFS】

Sum It Up Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6623   Accepted: 3439 Description Given a specified total t and a list of n integers, find all distinct sums using numbers from the list that add up to t. For example, if t = 4, n

POJ 3620--Avoid The Lakes【DFS】

Avoid The Lakes Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6775   Accepted: 3620 Description Farmer John's farm was flooded in the most recent storm, a fact only aggravated by the information that his cows are deathly afraid of wate

POJ 1321--棋盘问题【DFS】

棋盘问题 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 28147   Accepted: 13918 Description 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C. Input 输入含有多组测试数据. 每组数据的第一行是两个正整数,n k,用一个空格隔开,表示

POJ 1664 放苹果【DFS】

题意:给出n个苹果,m个盘子,问有多少种不同的苹果放置方法 可以把它抽象为把一个数n,拆分成a1,a2,a3,---,am,使得它们的和为n, 话说这一题是学习的ppt里面的,它的思路就是搜索 搜索条件的设置:放置苹果到第k个盘子的时候,要求第k个盘子里面的苹果数目大于第k-1个盘子里面的苹果数目,如果大于,则把它放置在第k个盘子里,如果不大于,则继续放置苹果,如果剩下的苹果小于k-1个盘子里面的苹果,就停止这个分支的搜索 学搜索学的还是蒙蒙的--- 这一题如果自己模拟一下样例是怎么搜的,好理解

poj 3009 Curling 2.0 【DFS】

题意:从2出发,要到达3, 0可以通过,碰到1要停止,并且1处要变成0, 并且从起点开始沿着一个方向要一直前进,直至碰到1(或者3)处才能停止,(就是反射来反射去知道反射经过3).如果反射10次还不能到达3,就输出-1. 策略:深搜. 易错点,方向不容易掌握,并且,出题人把n, m顺序反了. 代码: #include<stdio.h> #include<string.h> int map[25][25]; int ans, n, m; const int dir[4][2] = {

poj 1011 Sticks 【DFS】+【剪枝】

题意:有未知根(长度一样)木棒(小于等于n),被猪脚任意的截成n段,猪脚(脑抽了)想知道被截之前的最短长度(我推测猪脚得了健忘症). 这道题光理解题意就花了好久,大意就是任意根被截后的木棒拼到一起,能不能组成s(<=n)根的相同的木棒, 例:数据 9  5 1 2 5 1 2 5 1 2 可以组成最短为6 的(5+1, 2+2+2)3根木棒. 策略:深搜. 不过要是传统的深搜的话,TLE妥妥的.所以要剪枝(所谓剪枝,就是多加几个限制条件). 话不多说直接上代码. 代码1: #include <

POJ 1753 Flip Game (DFS + 枚举)

题目:http://poj.org/problem?id=1753 这个题在开始接触的训练计划的时候做过,当时用的是DFS遍历,其机制就是把每个棋子翻一遍,然后顺利的过了,所以也就没有深究. 省赛前一次做PC2遇到了几乎一模一样的题,只不过是把棋盘的界限由4X4改为了5X5,然后一直跑不出结果来,但是当时崔老湿那个队过了,在最后总结的时候,崔老湿就说和这个题一样,不过要枚举第一行进行优化. 我以为就是恢复第一行然后第二行以此类推,不过手推一下结果是6不是4,就知道这个有问题. 问了崔老湿,问了+

poj 1088 滑雪 【记忆化搜索】+【DFS】

策略:如题 题目链接:http://poj.org/problem?id=1088 代码: #include<stdio.h> #include<string.h> int map[105][105], dp[105][105], n, m; const int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0}; //四个方向 int limit(int x, int y) //判断是不是越界了 { if(x<1||x>n||y<1||