武林 HDU - 1107

题目链接:https://vjudge.net/problem/HDU-1107

注意:题目中只有两个不同门派的人在同一个地方才能对决,其他情况都不能对决。

还有,这步的有效的攻击只有走到下一步之后才生效,所以会出现样例1和样例2的情况。

代码有注释,便于理解,这理我说一下vis[][][]数组的用处。

vis[x][x][1] 表示少林寺人的编号。

vis[x][x][2] 表示武当派人的编号。

vis[x][x][3] 表示峨眉派人的编号。

vis[x][x][4] 表示一个门派是否有超过两个人。


  1 #include 
  2 #include 
  3 #include 
  4 #include 
  5 #include 
  6 #include 
  7 #include 
  8 #include 
  9 using namespace std;
 10 
 11 typedef long long LL;
 12 #define inf (1LL << 25)
 13 #define rep(i,j,k) for(int i = (j); i <= (k); i++)
 14 #define rep__(i,j,k) for(int i = (j); i < (k); i++)
 15 #define per(i,j,k) for(int i = (j); i >= (k); i--)
 16 #define per__(i,j,k) for(int i = (j); i > (k); i--)
 17 
 18 const int N = 20;
 19 int vis[N][N][10];
 20 int steps;
 21 
 22 struct People{
 23 
 24     char c; //门派
 25     int tot;//标记
 26     int x,y;//坐标
 27     int dir;//方向 正负1来方便判断
 28     int nx,wx,sx;
 29 
 30     int att(){//攻击
 31         if(c == 'S') return (0.5 * nx + 0.5 * wx) * (sx * 1.0 + 10) /100;
 32         else if(c == 'W') return (0.8 * nx + 0.2 * wx) * (sx * 1.0 + 10) /100;
 33         else if(c == 'E') return (0.2 * nx + 0.8 * wx) * (sx * 1.0 + 10) /100;
 34     }
 35 
 36     //被攻击
 37     void is_att(int x) { sx -= x;}
 38 
 39     //移动
 40     void mv(){
 41         if(c == 'S'){
 42             if(!(x + dir >= 1 && x + dir <= 12)) dir = -dir;
 43             x += dir;
 44         }
 45         else if(c == 'W'){
 46             if(!(y + dir >= 1 && y + dir <= 12)) dir = -dir;
 47             y += dir;
 48         }
 49         else if(c == 'E'){
 50             int xx = x + dir;
 51             int yy = y + dir;
 52             if(!(xx >= 1 && xx <= 12 && yy >= 1 && yy <= 12)) dir = -dir;
 53             if(x + dir >= 1 && x + dir <= 12 && y + dir >= 1 && y + dir <= 12) x += dir, y += dir;
 54         }
 55     }
 56 
 57     //写下标记
 58     void vis_w(){
 59         if(c == 'S'){
 60             if(vis[x][y][1] == 0) vis[x][y][1] = tot;
 61             else vis[x][y][4] = 1;
 62         }
 63         else if(c == 'W'){
 64             if(vis[x][y][2] == 0) vis[x][y][2] = tot;
 65             else vis[x][y][4] = 1;
 66 
 67         }
 68         else if(c == 'E'){
 69             if(vis[x][y][3] == 0) vis[x][y][3] = tot;
 70             else vis[x][y][4] = 1;
 71         }
 72     }
 73 
 74     //擦除标记
 75     void vis_e(){
 76        rep(i,1,4) vis[x][y][i] = 0;
 77     }
 78 
 79 }p[1010];
 80 bool died[1010]; //该编号的人是否死亡
 81 int pl;//人数
 82 
 83 void work(){
 84 
 85     rep(q,1,steps){
 86         rep(i,1,12) rep(j,1,12){
 87 
 88             if(vis[i][j][4] == 1) continue; //一个门派超过两个人
 89             int a = 0,b = 0,num = 0;
 90             rep(p,1,3) if(vis[i][j][p] != 0){
 91                 num++;
 92                 if(!a) a = vis[i][j][p];
 93                 else b = vis[i][j][p];
 94             }
 95 
 96             if(num != 2) continue; //不是两个人
 97             
 98             int w1 = p[a].att();
 99             int w2 = p[b].att();
100             p[a].is_att(w2);
101             p[b].is_att(w1);
102         }
103 
104         rep(o,1,pl) if(!died[o]){
105             p[o].vis_e();//擦除标记
106             if(p[o].sx <= 0) died[o] = true;
107         }
108 
109         rep(o,1,pl) if(!died[o]){
110             p[o].mv();
111             p[o].vis_w();//标记
112         }
113     }
114 }
115 
116 void print(){
117 
118     int m[4] = {0};
119     int t[4] = {0};
120 
121     rep(o,1,pl){
122         if(died[o]) continue;
123 
124         if(p[o].c == 'S') m[1]++, t[1] += p[o].sx;
125         else if(p[o].c == 'W') m[2]++, t[2] += p[o].sx;
126         else if(p[o].c == 'E') m[3]++, t[3] += p[o].sx;
127     }
128 
129     cout << m[1] << ' ' << t[1] << endl;
130     cout << m[2] << ' ' << t[2] << endl;
131     cout << m[3] << ' ' << t[3] << endl;
132     cout << "***" << endl;
133 } 
134 
135 int main(){
136 
137     ios::sync_with_stdio(false);
138     cin.tie(0);
139 
140     int T;
141     cin >> T;
142     char in;
143     while(T--){
144 
145         pl = 0;
146         rep(i,1,1005) died[i] = false;
147         rep(i,1,15) rep(j,1,15) rep(k,1,4) vis[i][j][k] = 0;
148         cin >> steps;
149 
150         while(cin >> in){
151             if(in == '0'){
152                 break;
153             }
154 
155             ++pl;
156             p[pl].c = in;
157             p[pl].tot = pl;
158             p[pl].dir = 1;
159             cin >> p[pl].x >> p[pl].y >> p[pl].nx >> p[pl].wx >> p[pl].sx;
160             p[pl].vis_w();
161         }
162         work();
163         print();
164     }
165 
166     getchar(); getchar();
167     return 0;
168 }

 

你可能感兴趣的:(武林 HDU - 1107)