zoukankan      html  css  js  c++  java
  • 武林 HDU

    题目链接: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 <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <queue>
      6 #include <map>
      7 #include <cmath>
      8 #include <iomanip>
      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 }
  • 相关阅读:
    id设置为10000开始
    关于mysql显示1000条以上找不到的情况
    localhost进入首页css路径出错
    Unknown column 'a.root_id' in 'where clause'解决方法
    curd 里url传输汉字验证错误问题解决方法
    如何同时添加多条数据
    如何在已建好的表格中添加字段?
    sql一个表中两个字段合并求和
    三表联查,这是我目前写过的最长的sql语句,嗯嗯,果然遇到问题才能让我更快成长,更复杂的语句也有了一些心得了
    sql时间查询的问题
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/11329622.html
Copyright © 2011-2022 走看看