题目:https://cn.vjudge.net/problem/HDU-1107
题意:中文题干不再赘述,仅强调两处细节
(1)仅当一个格子里有两名弟子,且二者分属不同门派时才会发生战斗。
(2)每次战斗+移动称作一步,最后一次移动后的战斗不需处理。
思路:模拟题怎么写都能写出来,我提供几处的实现方法供参考。
(1)存储结构:滚动二维结构体数组,相当于两个二维数组,移动时将属性改变后的结构体放入新二维数组,清空旧二维数组。
(2)移动:在结构体内设dr,dc两成员变量分别表示行列上移动距离和方向,根据门派进行不同的初始化(少林弟子dr=1,dc=0;武当弟子dr=0,dc=1;峨眉弟子dr=1,dc=1;左下角右上角的峨眉弟子永远不会动dr=dc=0),每次移动时仅需判断是否触碰边界,进行反向,而不需对每种门派单独处理。
代码:C++11
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn = 20;
int n, m = 12, T;
struct Person
{
int r, c;
char type;
int hp, in, vio;
int dr, dc;
Person(int r, int c, char type, int in, int vio, int hp): r(r), c(c), type(type), hp(hp), in(in), vio(vio)
{
dr = dc = 1;
if(type == 'S')
dc = 0;
if(type == 'W')
dr = 0;
if(type == 'E' && ((r == m && c == 1) || (r == 1 && c == m)))
dr = dc = 0;
}
int getatk()
{
if(type == 'S')
{
return (0.5 * in + 0.5 * vio) * (hp + 10.0) / 100;
}
else if(type == 'W')
{
return (0.8 * in + 0.2 * vio) * (hp + 10.0) / 100;
}
else if(type == 'E')
{
return (0.2 * in + 0.8 * vio) * (hp + 10.0) / 100;
}
}
Person move()
{
#define inpic(r, c) (r >= 1 && r <= m && c >= 1 && c <= m)
if(!inpic(r + dr, c + dc))
{
dr = -dr;
dc = -dc;
}
r += dr;
c += dc;
return *this;
}
};
vector<Person> pic[2][maxn][maxn];
void clear(int p)
{
for(int i = 0; i < maxn; i++)
{
for(int j = 0; j < maxn; j++)
{
pic[p][i][j].clear();
}
}
}
inline bool battlecheck(vector<Person> &v)
{
if(v.size() != 2)
return false;
return v[0].type != v[1].type;
}
void battle(int p)
{
auto &upic = pic[p];
for(int i = 1; i <= m; i++)
{
for(int j = 1; j <= m; j++)
{
if(battlecheck(upic[i][j]))
{
int atk0 = upic[i][j][0].getatk();
int atk1 = upic[i][j][1].getatk();
upic[i][j][0].hp -= atk1;
upic[i][j][1].hp -= atk0;
}
}
}
}
void move(int p, int tp)
{
for(int i = 1; i <= m; i++)
{
for(int j = 1; j <= m; j++)
{
for(auto &t : pic[p][i][j])
{
if(t.hp > 0)
{
Person np = t.move();
pic[tp][np.r][np.c].push_back(np);
}
}
}
}
}
void solve()
{
int p = 0;
for(int cnt = 0; cnt < T; cnt++)
{
int tp = (p + 1) % 2;
battle(p);
move(p, tp);
clear(p);
p = tp;
}
int scnt = 0, wcnt = 0, ecnt = 0;
int shp = 0, whp = 0, ehp = 0;
for(int i = 1; i <= m; i++)
{
for(int j = 1; j <= m; j++)
{
for(auto &t : pic[p][i][j])
{
if(t.hp <= 0)
continue;
if(t.type == 'S')
{
scnt++;
shp += t.hp;
}
else if(t.type == 'W')
{
wcnt++;
whp += t.hp;
}
else if(t.type == 'E')
{
ecnt++;
ehp += t.hp;
}
}
}
}
cout << scnt << " " << shp << endl;
cout << wcnt << " " << whp << endl;
cout << ecnt << " " << ehp << endl;
cout << "***" << endl;
}
int main()
{
ios::sync_with_stdio(false);
int cases;
cin >> cases;
while(cases--)
{
clear(0);
clear(1);
cin >> T;
char type;
while(cin >> type && type != '0')
{
int r, c, in, vio, hp;
cin >> r >> c >> in >> vio >> hp;
pic[0][r][c].push_back(Person(r, c, type, in, vio, hp));
}
solve();
}
return 0;
}