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

来源:互联网 发布:安卓版爱剪辑软件 编辑:程序博客网 时间:2024/06/10 07:22

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

分析:
      首先我们可以发现,能到的点构成的集合,每个点都是可以两两互达的,这样可以保证一个点尽量不走两遍。
      其次,我们在从起点选择一个方向走出一个点集后,点集中那些没有被攻击过的点设为p,我们在选择另外的方向走的第一步如果已经在p中,那么这个方向无需再走。
      接着就看造化了…(代码高仿hza,大牛勿喷…)

AC 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_JUDGEtypedef 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;}
0 0
原创粉丝点击