sgu245:Black-White Army(技巧暴力)
2015-06-01 19:45
225 查看
题目大意:
~~~~~~给定一个n∗mn*m的国际象棋棋盘,上面有卒(只能向左上右上攻击)、车、马、象、后、王。告诉你的初始位置,你可以选择车、马、象、王走(选择一个之后就不能变了),每干掉一个棋子有一个收益,被干掉之后有一个损失并结束游戏,求出最大收益。
分析:
~~~~~~首先我们可以发现,能到的点构成的集合,每个点都是可以两两互达的,这样可以保证一个点尽量不走两遍。
~~~~~~其次,我们在从起点选择一个方向走出一个点集后,点集中那些没有被攻击过的点设为pp,我们在选择另外的方向走的第一步如果已经在pp中,那么这个方向无需再走。
~~~~~~接着就看造化了…(代码高仿hzahza,大牛勿喷…)
AC code:
~~~~~~给定一个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; }
相关文章推荐
- 凯云水利水电工程造价系统 (四) 配合比单价模块
- EXCEL: 数字格式不一样导致VLOOKUP无法正常使用
- Spring MVC的@ResponseBody返回JSON串时Content-Type编码问题
- Android---手动创建线程与GUI线程同步(二)
- Linux--YUM 安装 nginx php mysql
- C#第五次作业:开源项目“网页正文提取”的理解
- 回忆是个陷阱,不小心掉进往事的长河,那些过往的殇,就会把我拖进沼泽
- 织梦返回上一页面
- 2015推荐的Android框架
- github检出方式注意事项
- linux内的正则表达式
- Remove Duplicates from Sorted Array II
- 关于Struts2国际化问题。
- 校验maven配置文件
- 梦入你的世界
- python文件拷贝
- Java和Python使用有道词典制作查单词脚本
- POI--帮助文档
- POI--帮助文档
- Linux网络编程:原始套接字编程及实例分析(3)