您的位置:首页 > 其它

sgu245:Black-White Army(技巧暴力)

2015-06-01 19:45 225 查看
题目大意:

~~~~~~给定一个n∗mn*m的国际象棋棋盘,上面有卒(只能向左上右上攻击)、车、马、象、后、王。告诉你的初始位置,你可以选择车、马、象、王走(选择一个之后就不能变了),每干掉一个棋子有一个收益,被干掉之后有一个损失并结束游戏,求出最大收益。

分析:

~~~~~~首先我们可以发现,能到的点构成的集合,每个点都是可以两两互达的,这样可以保证一个点尽量不走两遍。

~~~~~~其次,我们在从起点选择一个方向走出一个点集后,点集中那些没有被攻击过的点设为pp,我们在选择另外的方向走的第一步如果已经在pp中,那么这个方向无需再走。

~~~~~~接着就看造化了…(代码高仿hzahza,大牛勿喷…)

AC code:

[code]#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <string>
#include <sstream>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <stack>
#include <queue>
#include <vector>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define pot pair<int,int>
#define ONLINE_JUDGE
typedef long long LL;
typedef double DB;
typedef long double LD;
using namespace std;

const int MAXN = 309;

int n, m;
char g[MAXN][MAXN];
int cost[7], lose;
int sx, sy;
int ans;

int num(char c)
{
    if(c == '.') return 0;
    else if(c == '#') return -1;
    else if(c == 'P') return 1;
    else if(c == 'R') return 2;
    else if(c == 'K') return 3;
    else if(c == 'B') return 4;
    else if(c == 'Q') return 5;
    else return 6;
}

int xk[8] = {-1,-2,-2,-1,1,2,2,1};
int yk[8] = {-2,-1,1,2,-2,-1,1,2};
int xq[8] = {-1,-1,-1,0,1,1,1,0};
int yq[8] = {-1,0,1,1,1,0,-1,-1};
int xr[4] = {-1,0,1,0};
int yr[4] = {0,1,0,-1};
int xb[4] = {1,1,-1,-1};
int yb[4] = {-1,1,-1,1};

int attack[MAXN][MAXN];
int attack2[MAXN][MAXN];
int sta[MAXN][MAXN];
bool vis[MAXN][MAXN];

vector<pot> go(char c, const pot &s, bool flag)
{
    int x, y;
    int tx, ty;
    x = s.fi, y = s.se;
    vector<pot> ret;
    switch(c)
    {
        case 'P':
            if(g[x-1][y-1] != '#') ret.pb(mp(x-1, y-1));
            if(g[x-1][y+1] != '#') ret.pb(mp(x-1, y+1));
            break;
        case 'R':
            for(int i = 0; i < 4; ++i)
            {
                tx = x+xr[i], ty = y+yr[i];
                while(g[tx][ty] == '.')
                {
                    if(flag && !attack[tx][ty]) break;
                    ret.pb(mp(tx, ty));
                    tx += xr[i], ty += yr[i];
                }
                if(g[tx][ty] != '#') ret.pb(mp(tx, ty));
            }
            break;
        case 'K':
            for(int i = 0; i < 8; ++i)
            {
                tx = x+xk[i], ty = y+yk[i];
                if(g[tx][ty] != '#') ret.pb(mp(tx, ty));
            }
            break;
        case 'B':
            for(int i = 0; i < 4; ++i)
            {
                tx = x+xb[i], ty = y+yb[i];
                while(g[tx][ty] == '.')
                {
                    if(flag && !attack[tx][ty]) break;
                    ret.pb(mp(tx, ty));
                    tx += xb[i], ty += yb[i];   
                }
                if(g[tx][ty] != '#') ret.pb(mp(tx, ty));
            }
            break;
        case 'Q':
            for(int i = 0; i < 8; ++i)
            {
                tx = x+xq[i], ty = y+yq[i];
                while(g[tx][ty] == '.')
                {
                    if(flag && !attack[tx][ty]) break;
                    ret.pb(mp(tx, ty));
                    tx += xq[i], ty += yq[i];   
                }
                if(g[tx][ty] != '#') ret.pb(mp(tx, ty));    
            }
            break;
        case 'M':
            for(int i = 0; i < 8; ++i)
            {
                tx = x+xq[i], ty = y+yq[i];
                if(g[tx][ty] != '#') ret.pb(mp(tx, ty));    
            }
            break;
    }
    return ret;
}

int solve(char c, const pot &s)
{
    memset(vis, false, sizeof vis);
    memset(attack2, 0, sizeof attack2);
    pot now, to;
    int ret = 0, tmpans;
    vector<pot> st, p;
    queue<pot> q;
    for(int i = 2; i <= n+1; ++i)
        for(int j = 2; j <= m+1; ++j)
            if(num(g[i][j]) >= 1)
            {
                st = go(g[i][j], mp(i, j), 0);
                for(int k = 0, sz = st.size(); k < sz; ++k)
                    attack2[st[k].fi][st[k].se]++;
            }
    memcpy(attack, attack2, sizeof attack);
    st = go(c, s, 1);
    for(int i = 0, sz = st.size(); i < sz; ++i)
    {
        now = st[i], tmpans = 0;
        if(vis[now.fi][now.se]) continue;
        memcpy(attack, attack2, sizeof attack);
        memset(sta, 0, sizeof sta);
        if(attack[now.fi][now.se]) sta[now.fi][now.se] = 2;
        else q.push(now), sta[now.fi][now.se] = 1;
        while(!q.empty())
        {
            now = q.front();q.pop();
            if(num(g[now.fi][now.se]) >= 1)
            {
                tmpans += cost[num(g[now.fi][now.se])];
                ret = max(ret, tmpans);
                p = go(g[now.fi][now.se], now, 0);
                for(int j = 0, sz = p.size(); j < sz; ++j)
                {
                    to = p[j];
                    --attack[to.fi][to.se];
                    if(!attack[to.fi][to.se] && sta[to.fi][to.se] == 2)
                    {
                        sta[to.fi][to.se] = 1;
                        q.push(to);
                    }
                }
            }
            p = go(c, now, 1);
            for(int j = 0, sz = p.size(); j < sz; ++j)
            {
                to = p[j];
                if(!attack[to.fi][to.se] && !sta[to.fi][to.se])
                {
                    sta[to.fi][to.se] = 1;
                    q.push(to);
                }
                else if(attack[to.fi][to.se] && !sta[to.fi][to.se])
                    sta[to.fi][to.se] = 2;
            }
        }
        for(int p = 2; p <= n+1; ++p)
            for(int q = 2; q <= m+1; ++q)
                if(sta[p][q] == 1) vis[p][q] = true;
                else if(sta[p][q] == 2) ret = max(ret, tmpans+cost[num(g[p][q])]-lose);
    }
    return ret;
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif

    cin >> n >> m;
    for(int i = 1; i <= 6; ++i)
        cin >> cost[i];
    cin >> lose;
    for(int i = 2; i <= n+1; ++i)
        for(int j = 2; j <= m+1; ++j)
        {
            cin >> g[i][j];
            if(g[i][j] == '@') 
            {
                g[i][j] = '.';
                sx = i, sy = j;
            }
        }
    for(int i = 0; i <= n+2; ++i)
        g[i][0] = g[i][1] = g[i][m+2] = g[i][m+3] = '#';
    for(int i = 0; i <= m+2; ++i)
        g[0][i] = g[1][i] = g[n+2][i] = g[n+3][i] = '#';
    ans = max(ans, solve('K', mp(sx, sy)));
    ans = max(ans, solve('B', mp(sx, sy)));
    ans = max(ans, solve('R', mp(sx, sy)));
    ans = max(ans, solve('M', mp(sx, sy)));
    cout << ans << endl;

    #ifndef ONLINE_JUDGE
    fclose(stdin);
    fclose(stdout);
    #endif
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: