HDU 2821 DFS

来源:互联网 发布:淘宝抢购时间 编辑:程序博客网 时间:2024/06/07 18:28

HDU 2821

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=2821

题意:

给一个矩阵,每个格子可能有权值或者没有。

现在有矩阵运动的规则如下,自己确定一个起始点,每次确定一个方向就会一直走下去,直到碰到有权值的单元。碰到有权值的单元时,会消掉一个单位的权值,并且把剩余的权值按照原来的方向推给下一个格子(此处看错题WA一次)。

求一种起始点和上下左右方向,消除所有权值。

思路:

我的250行超级大模拟过了啊!!!

然而并不需要那么sb

如果只是枚举上下左右方向,然后用while循环走完剩下的路,判断是否合法的话,也是不会超时的,这样也会少了很多冗余代码。再写一个。

好吧看懂思路半个小时就写完了。大模拟写了大概4个小时?

源码:

大模拟版

#include <cstdio>

#include <cmath>

#include <cstring>

#include <cstdlib>

#include <algorithm>

#include <iostream>

#include <queue>

#include <string>

using namespace std;

const int MAXN = 30;

char ans[MAXN*MAXN*MAXN];

char sstr[MAXN][MAXN];

char str[MAXN][MAXN];

int numx[MAXN], numy[MAXN];

int n, m;

bool check()

{

//    printf("sstr\n");

//    for(int i = 1 ; i <= n ; i++){

//        for(int j = 1 ; j <= m ; j++)

//            printf("%d ", sstr[i][j]);

//        printf("\n");

//    }

//    printf("sstr\nans   ");

//    for(int i = 0 ; ans[i] != '\0' ; i++)

//        printf("%c", ans[i]);

//    printf("\n\n");

    for(int i = 1 ; i <= n ; i++)

        for(int j = 1 ; j <= m ; j++)

            if(sstr[i][j])  return false;

    return true;

}

int DFS(int x, int y, int now);

int Up(int x, int y, int now);

int Down(int x, int y, int now);

int Left(int x, int y, int now);

int Right(int x, int y, int now);

int main()

{

    while(scanf("%d%d", &m, &n) != EOF){

        memset(numx, 0, sizeof(numx));

        memset(numy, 0, sizeof(numy));

        memset(sstr, 0, sizeof(sstr));

        for(int i = 1 ; i <= n ; i++){

            scanf("%s", str[i] + 1);

            for(int j = 1 ; j <= m ; j++){

                if(str[i][j] == '.'){

                    continue;

                }

                else if(str[i][j] == 'a'){

                    numx[i]++;

                    numy[j]++;

                    sstr[i][j] = 1;

                }

                else if(str[i][j] >= 'b'){

                    numx[i] += 2;

                    numy[j] += 2;

                    sstr[i][j] = str[i][j] - 'a' + 1;

                }

            }

        }

        int ok = 0;

        for(int i = 1 ; i <= n ; i++){

            for(int j = 1 ; j <= m ; j++){

                if(ok = DFS(i, j, 0)){

                    printf("%d\n%d\n", i - 1 , j - 1);

                    break;

                }

            }

            if(ok)

                break;

        }

        for(int i = 0 ; i < ok ; i++)

            printf("%c", ans[i]);

        printf("\n");

    }

    return 0;

}

 

int DFS(int x, int y, int now)

{

    if(sstr[x][y])

        return 0;

//    printf("now = %d, x = %d, y = %d\n", now, x - 1, y - 1);

    int res = 0;

    if(check()){

        ans[now] = '\0';

        return now;

    }

    res = Right(x, y, now);

    if(res)

        return res;

    else if(sstr[x][m] == 1 && y < m - 1){

        sstr[x][m] = 0;

        ans[now] = 'R';

        res = DFS(x, m, now + 1);

        if(res)

            return res;

        else{

            sstr[x][m] = 1;

        }

    }

    res = Left(x, y, now);

    if(res)

        return res;

    else if(sstr[x][1] == 1 && y > 2){

        sstr[x][1] = 0;

        ans[now] = 'L';

        res = DFS(x, 1, now + 1);

        if(res)

            return res;

        else{

            sstr[x][1] = 1;

        }

    };

    res = Down(x, y, now);

    if(res)

        return res;

    else if(sstr[n][y] == 1 && x < n - 1){

        sstr[n][y] = 0;

        ans[now] = 'D';

        res = DFS(n, y, now + 1);

        if(res)

            return res;

        else{

            sstr[n][y] = 1;

        }

    }

    res = Up(x, y, now);

    if(res)

        return res;

    else if(sstr[1][y] == 1 && x > 2){

        sstr[1][y] = 0;

        ans[now] = 'U';

        res = DFS(1, y, now + 1);

        if(res)

            return res;

        else{

            sstr[1][y] = 1;

        }

    }

    return 0;

}

int Up(int x, int y, int now)

{

    if(x == 1 || sstr[x-1][y] != 0)

        return 0;

    for(int i = x - 2 ; i >= 2 ; i--){

        if(sstr[i][y] != 0){

            ans[now] = 'U';

            int tsstr1 = sstr[i][y];

            int tsstr2 = sstr[i - 1][y];

            sstr[i - 1][y] += sstr[i][y] - 1;

            sstr[i][y] = 0;

            int ok = DFS(i, y, now + 1);

            if(ok)

                return ok;

            else{

                sstr[i][y] = tsstr1;

                sstr[i - 1][y] = tsstr2;

                return false;

            }

        }

    }

    return false;

}

int Down(int x, int y, int now)

{

    if(x == n || sstr[x + 1][y] != 0)

        return 0;

    for(int i = x + 2 ; i <= n - 1 ; i++){

        if(sstr[i][y] != 0){

            ans[now] = 'D';

            int tsstr1 = sstr[i][y];

            int tsstr2 = sstr[i + 1][y];

            sstr[i + 1][y] += sstr[i][y] - 1;

            sstr[i][y] = 0;

            int ok = DFS(i, y, now + 1);

            if(ok)

                return ok;

            else{

                sstr[i][y] = tsstr1;

                sstr[i + 1][y] = tsstr2;

                return 0;

            }

        }

    }

    return 0;

}

int Left(int x, int y, int now)

{

    if(y == 1 || sstr[x][y - 1] != 0)

        return 0;

    for(int i = y - 1 ; i >= 2 ; i--){

        if(sstr[x][i] != 0){

            ans[now] = 'L';

            int tsstr1 = sstr[x][i];

            int tsstr2 = sstr[x][i - 1];

            sstr[x][i - 1] += sstr[x][i] - 1;

            sstr[x][i] = 0;

            int ok = DFS(x, i, now + 1);

            if(ok)

                return ok;

            else{

                sstr[x][i] = tsstr1;

                sstr[x][i-1] = tsstr2;

                return 0;

            }

        }

    }

    return 0;

}

int Right(int x, int y, int now)

{

    if(y == m || sstr[x][y + 1] != 0)

        return 0;

    for(int i = y + 1 ; i <= m - 1 ; i++){

        if(sstr[x][i] != 0){

//            if(x == 2 && y == 2 && now == 2)

//                printf("i = %d\n", i);

            ans[now] = 'R';

            int tsstr1 = sstr[x][i];

            int tsstr2 = sstr[x][i + 1];

            sstr[x][i + 1] += sstr[x][i] - 1;

            sstr[x][i] = 0;

            int ok = DFS(x, i, now + 1);

            if(ok)

                return ok;

            else{

                sstr[x][i] = tsstr1;

                sstr[x][i+1] = tsstr2;

                return ok;

            }

        }

    }

    return 0;

}

/*

7

3

.......

.a...b.

.......

*/

简单深搜版

#include <cstdio>

#include <cstring>

#include <cstdlib>

#include <cmath>

#include <algorithm>

#include <iostream>

using namespace std;

const int MAXN = 30;

char str[MAXN][MAXN];

int sstr[MAXN][MAXN];

int ans[MAXN*MAXN*MAXN];

int dx[] = {-1, 0, 1, 0};

int dy[] = {0, 1, 0, -1};

int n, m;

int sum;

bool valid_pos(int x, int y)

{

    if(x < 0 || x >= n)

        return false;

    if(y < 0 || y >= m)

        return false;

    return true;

}

int DFS(int x, int y, int step)

{

    if(step >= sum)

        return step;

    for(int i = 0 ; i < 4 ; i++){

//        if(x == 4 && y == 1)

//            printf("i = %d\n", i);

        int tx = dx[i] + x;

        int ty = dy[i] + y;

        if(!valid_pos(tx, ty) || sstr[tx][ty])

            continue;

        while(valid_pos(tx + dx[i], ty + dy[i]) && !sstr[tx+dx[i]][ty+dy[i]])

            tx += dx[i], ty += dy[i];

        tx += dx[i], ty += dy[i];

        if(!valid_pos(tx, ty))

            continue;

        else if(sstr[tx][ty] > 1 && !valid_pos(tx + dx[i], ty + dy[i]))

            continue;

        int temp = sstr[tx][ty];

        sstr[tx][ty] = 0;

        sstr[tx + dx[i]][ty + dy[i]] += temp - 1;

        ans[step] = i;

        int ok = DFS(tx, ty, step + 1);

        if(ok)  return ok;

        sstr[tx][ty] = temp;

        sstr[tx + dx[i]][ty + dy[i]] -= temp - 1;

    }

    return 0;

}

int solve()

{

    int ok = 0;

    for(int i = 0 ; i < n ; i++){

        for(int j = 0 ; j < m ; j++){

            if(sstr[i][j] == 0)

                ok = DFS(i, j, 0);

            if(ok){

                printf("%d\n%d\n", i, j);

                return ok;

            }

        }

    }

}

char toC(int a)

{

    if(a == 0)

        return 'U';

    else if(a == 1)

        return 'R';

    else if(a == 2)

        return 'D';

    else if(a == 3)

        return 'L';

}

int main()

{

    while(scanf("%d%d", &m, &n) != EOF){

        sum = 0;

        for(int i = 0 ; i < n ; i++){

            scanf("%s", str[i]);

            for(int j = 0 ; j < m ; j++){

                if(str[i][j] == '.')

                    sstr[i][j] = 0;

                else{

                    sstr[i][j] = str[i][j] - 'a' + 1;

                    sum += sstr[i][j];

                }

            }

        }

        int ok = solve();

        for(int i = 0 ; i < ok ; i++){

            printf("%c", toC(ans[i]));

        }

        printf("\n");

    }

    return 0;

}

 

0 0
原创粉丝点击