bfs或者dfs Good Bye 2016 D

http://codeforces.com/contest/750/problem/D

题目大意:

放鞭炮,鞭炮会爆炸n次,每次只会往目前前进方向的左上和右上放出他的子鞭炮。问,最后能有多少格子被覆盖?

思路:

感觉是期末复习阶段太久没有敲代码了的缘故吧,记忆化搜索的状态找的都不准确了。

bfs,然后定义dp(x,y,z,dir)表示在(x,y)这个位置,第z次爆炸,爆炸方向为dir。如果这个状态存在,就不放入队列。

//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha
")
/*
定义:dp(x, y, t, dir = 8),当前在坐标(x, y)这个位置,朝向为dir,将要从这点开始走t步(假定,向上是+,向下是-.),是否走过这个状态
*/
const int maxpos = 400 + 10;
int dp[maxpos][maxpos][40][8];
int color[maxpos][maxpos];
int n;
int t[maxpos];
pair<int, int> dir[8];

void init(){
    cin >> n;
    for (int i = 1; i <= n; i++){
        scanf("%d", t + i);
    }
    ///逆时针标号
    dir[0] = mk(1, 1), dir[1] = mk(0, 1), dir[2] = mk(-1, 1), dir[3] = mk(-1, 0);
    dir[4] = mk(-1, -1), dir[5] = mk(0, -1), dir[6] = mk(1, -1), dir[7] = mk(1, 0);
}

struct Point{
    int x, y, aim;
};

int bfs(){
    if (n == 1) return t[1];
    t[n + 1] = 10;
    int x = 200, y = 200;
    //dp[x][y + 1][t[1] - 1][1] = 1;
    queue<Point> que;
    for (int i = 1; i <= t[1]; i++){
        int nx = dir[1].fi + x, ny = dir[1].se + y;
        color[nx][ny] = 1;
        x = nx, y = ny;
    }
    //printf("x = %d y = %d
", x, y);
    que.push(Point{x, y, 2});
    que.push(Point{x, y, 0});
    dp[x][y][2][2] = 1;
    dp[x][y][2][0] = 1;
    for (int i = 2; i <= n; i++){
        queue<Point> tmp;
        while (!que.empty()){
            Point from = que.front(); que.pop();
            //printf("%d %d
", from.x, from.y);
            for (int j = 1; j <= t[i]; j++){
                int nx = from.x + dir[from.aim].fi, ny = from.y + dir[from.aim].se;
                color[nx][ny] = 1;
                from.x = nx, from.y = ny;
                //printf("nx = %d ny = %d
", nx, ny);
            }
            int lb = (from.aim + 1) % 8, rb = (from.aim - 1 + 8) % 8;
            if (dp[from.x][from.y][i][lb] == 0){
                tmp.push(Point{from.x, from.y, lb});
                dp[from.x][from.y][i][lb] = 1;
            }
            if (dp[from.x][from.y][i][rb] == 0){
                tmp.push(Point{from.x, from.y, rb});
                dp[from.x][from.y][i][rb] = 1;
            }
        }
        que = tmp;
    }
    int ans = 0;
    for (int i = 0; i < 405; i++){
        for (int j = 0; j < 405; j++){
            ans += color[i][j];
            //if (color[i][j]) printf("x = %d y = %d
", i, j);
        }
    }
    return ans;
}

int main(){
    init();
    printf("%d
", bfs());
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/heimao5027/p/6273901.html