HDU 2821Pusher(DFS )

题意:是一个游戏,可以玩下,就很清楚了,给你有箱子的图,你现在选择一个初始位置,并确定推的方向序列,规则:你要和箱子至少有一个空格才可以推,每次是先拿掉一个箱子,再把剩余的箱子(如果还存在的话)推向下一格,选择一个方向后要一直沿着这个方向走到不能走为止。

#include<bits/stdc++.h>
#define cl(a,b) memset(a,b,sizeof(a));
#define LL long long
#define out(x) cout<<x<<endl;
using namespace std;
const int maxn=30;
const int inf=9999999;
char tmp[maxn][maxn];
int n,m;
int a[maxn][maxn];
int dir[][2]={{1,0},{0,1},{-1,0},{0,-1}};
char dirr[]="DRUL";//对应dir的方向
char path[maxn*105];//记录方向序列
int allNum;//所有的箱子数
bool pan(int x,int y){
    if(x>=0&&x<n&&y>=0&&y<m)return true;
    return false;
}
bool dfs(int x,int y,int num){
    if(num==allNum){
        path[num]=0;
        return true;
    }
    for(int i=0;i<4;i++){
        int xx=x+dir[i][0];
        int yy=y+dir[i][1];
        if(!pan(xx,yy)||a[xx][yy])continue;//判断从(x,y)这一方向出发是否合法,1.在图里,2.不能有箱子
        while(pan(xx,yy)&&!a[xx][yy]){//沿着这个方向继续探测
            xx+=dir[i][0];
            yy+=dir[i][1];
        }
        if(!pan(xx,yy))continue;//判断while结束的条件
        int t=a[xx][yy];
        a[xx+dir[i][0]][yy+dir[i][1]]+=t-1;
        path[num]=dirr[i];
        a[xx][yy]=0;
        if(dfs(xx,yy,num+1))return true;
        a[xx+dir[i][0]][yy+dir[i][1]]-=t-1;//回溯把图复原
        a[xx][yy]=t;
    }
    return false;
}

int main(){

    while(~scanf("%d%d",&m,&n)){
        allNum=0;
        for(int i=0;i<n;i++){
            scanf("%s",tmp[i]);
            for(int j=0;j<m;j++){
                if(tmp[i][j]>=‘a‘&&tmp[i][j]<=‘z‘){
                    allNum+=tmp[i][j]-‘a‘+1;
                    a[i][j]=tmp[i][j]-‘a‘+1;
                }
                else {
                    a[i][j]=0;
                }
            }
        }

        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++)if(!a[i][j]&&dfs(i,j,0)){
                printf("%d\n%d\n%s\n",i,j,path);
                goto A;
            }
        }
        A:;
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-13 06:39:58

HDU 2821Pusher(DFS )的相关文章

HDU 1010:(DFS)

需要在确切的时间到达D处 此题特殊的地方在于剪枝方法:根据所处点与D处的曼哈顿距离和所剩步数的奇偶性剪枝.如果两者奇偶性不同,直接return #include"cstdio" #include"cmath" #include"cstring" #include"iostream" #include"queue" #define MAXN 10 using namespace std; int dx[4]=

hdu 1016 Prime Ring Problem (dfs)

一切见注释. #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; bool vis[22]; int n; int ans[22]; int top; bool isprime(int x)//判断素数 { for(int i=2;i<x;i++) if(x%i==0)return false; return

HDU 2209 翻纸牌游戏(dfs)

翻纸牌游戏 Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2180    Accepted Submission(s): 787 Problem Description 有一种纸牌游戏,很有意思,给你N张纸牌,一字排开,纸牌有正反两面,开始的纸牌可能是一种乱的状态(有些朝正,有些朝反),现在你需要整理这些纸牌.但是麻烦的是,每当你翻一张

HDU 1695(GCD)

GCD Time Limit: 3000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u [Submit]   [Go Back]   [Status] Description Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y) = k. GCD(x, y) means the greatest common

POJ 3087 Shuffle&#39;m Up (DFS)

题目链接:Shuffle'm Up 题意:有a和b两个长度为n的字符序列,现定义操作: 将a.b的字符交叉合并到一个序列c,再将c最上面的n个归为a,最下面n个归为b 给出a,b和目标序列c,问最少多少次操作a.b转化为c 解析:将a.b放入哈希表,然后模拟操作过程直接dfs即可. AC代码: #include <cstdio> #include <iostream> #include <cstring> #include <map> using names

hdu 1874(Dijkstra )

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1874 畅通工程续 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 27692    Accepted Submission(s): 10019 Problem Description 某省自从实行了很多年的畅通工程计划后,终于修建了很多路.不过路

LeetCode Subsets (DFS)

题意: 给一个集合,有n个互不相同的元素,求出所有的子集(包括空集,但是不能重复). 思路: DFS方法:由于集合中的元素是不可能出现相同的,所以不用解决相同的元素而导致重复统计. 1 class Solution { 2 public: 3 vector<vector<int>> subsets(vector<int>& nums) { 4 sort(nums.begin(),nums.end()); 5 DFS(0,nums,tmp); 6 return a

POJ 1699 Best Sequence(DFS)

題目鏈接 題意 : 將幾個片段如圖所示方法縮成一個序列,求出最短這個序列. 思路 : 其實我也不知道怎麼做.....看網上都用了DP.....但是我不會.....這個DP不錯,還有用KMP+状压DP做的 1 //1699 2 #include <iostream> 3 #include <stdio.h> 4 #include <string.h> 5 #include <string> 6 7 using namespace std; 8 9 string

LeetCode Subsets II (DFS)

题意: 给一个集合,有n个可能相同的元素,求出所有的子集(包括空集,但是不能重复). 思路: 看这个就差不多了.LEETCODE SUBSETS (DFS) 1 class Solution { 2 public: 3 vector<vector<int>> subsets(vector<int>& nums) { 4 sort(nums.begin(),nums.end()); 5 DFS(0,nums,tmp); 6 ans.push_back(vector