• 10.09T3 大模拟


    Rainbow擅长玩战棋类游戏。著名的战棋游戏有很多,例如《曹操传》、《瓦岗山异闻录》等。在本题中,我们考虑战棋游戏的一个简单版本,基于以下规则:
    地图
    地图是一个N行M列的矩阵,矩阵中的不同位置有不同的地形,例如平原、树林、山地、河流、雪原等。在这里,我们给矩阵中的每个位置规定一个正整数,这个整数会对在矩阵中的移动产生影响。
    角色
    每个角色均可被视作位于矩阵中某个位置上的人物。每个角色具有生命值HP, 攻击力AT, 移动力MV和攻击范围[AD1 AD2]。角色被分为两个阵营,第0阵营被玩家控制,第1阵营被系统控制。
    当两个不同阵营的角色p和q的曼哈顿距离处于p的攻击范围内(包含端点)时,p可以攻击q。若q被p攻击,则q的生命值被减去p的攻击力。当一个角色的生命值<=0时,它将立即被移除出地图,离开游戏。
    每个角色均占领地图上的一个位置,并且可以在地图上移动,遵循以下规则:
    占领
    最初,每个角色在地图的不同位置生成。他们各自占领自己所在的位置。当一个角色在移动时,其它角色均不能移动。 
    一个角色开始移动前失去对所在位置的占领权,停止移动时获得所在位置的占领权。
    “移动”与“步”
    一次移动由若干步组成。在每一步中,一个角色可以从当前位置走向四个方向上相邻的位置,但不能走到被其它角色占领的位置上。
    当一个角色从i,j 走到x,y 时, 它的移动力会被扣除Gx,y。使得移动力变为负数的“步”是不合法的。在合法的一“步”完成后,若该角色正处于与对方阵营某个角色相邻(四个方向)的位置上,则该角色的移动力立即被减为0,换句话说,他将不能再走另外一步。
    当一次“移动”结束后,角色的移动力恢复为初始值。
    能被一个角色通过若干合法“步”到达的位置集合称为该角色的移动范围。停留在原地也是合法的,故也被算入移动范围。
    游戏的过程由若干轮组成,每轮玩家阵营先行动,系统阵营后行动。对于每个阵营,该阵营的所有角色轮流行动。在每次行动中,一个角色先移动到移动范围内的任意一个位置,然后可能会攻击对方阵营的一个角色(或什么也不做)。 当一个阵营的所有角色均被移除出地图时,另外一个阵营获胜。
    Rainbow得到了一份游戏日志,请帮他复原这个游戏的过程。

    Input

    第一行 4 个整数 N,M,C,E(1≤N,M≤100,2≤C≤min(N×M,100),1≤E≤3000) 表示地图行数、列数、角色数、日志事件数。 接下来N行每行M个整数Gi,j(1≤Gi,j≤10^2) 。
    接下来 C 行每行 8 个整数 HP,AT,MV,AD 1 ,AD 2 ,ST x ,ST y ,GR(1≤HP,AT,MV≤10^3, 1≤AD1≤AD2≤20,1≤STx≤N,1≤STy≤M,0≤GR≤1) , 表示角色的 5 个属性以及初始位置、所属阵营。 
    接下来 E 行描述日志中的事件,每个事件都是以下格式之一: 
    Round of GR – 阵营 GR 行动回合开始。 
    Action of character ID – 角色ID 行动开始。 
    Move to (x,y) – 当前行动角色通过若干步移动到 (x,y) 。 
    Attack ID – 当前行动角色攻击角色ID 但是角色 ID在攻击后未被移除。 
    Drive out ID – 当前行动角色攻击角色ID并造成ID 被移出游戏。
    在事件中,1≤x≤N,1≤y≤M,1≤ID≤C,0≤GR≤1 。 行列标号从1开始,每个阵营初始至少拥有1个角色。

    Output

    对于每个Move to事件, 若无法到达,输出“INVALID”,否则输出当它进入终点,准备结束“移动”前最多剩余多少移动力(移动力变化的优先顺序为:减去G→ G→ 若与对方阵营相邻扣为 0→ 0→ 输出→ → 恢复初始值)。 
    对于每个Attack or Drive out事件,若不能攻击或者攻击造成的是否移出地图的情况与输入不相符,输出“INVALID”,否则输出攻击后被攻击角色剩余 HP HP 。 
    不合法的事件在处理后续事件时应当被忽略。数据保证输入完成时游戏恰好结束,并且Round of and Action of类事件被正确记录,没有缺失或者矛盾。

    样例输入1

    样例输出1

    5 5 4 12

    1 9 1 4 4

    1 9 1 2 4

    1 9 1 1 2

    2 9 2 7 3

    2 3 2 6 1

    10 5 8 1 3 1 1 0

    20 10 5 1 2 2 1 0

    19 10 5 1 2 5 2 1

    25 25 3 1 1 5 5 0

    Round of 0

    Action of character 2

    Move to (5,1)

    Attack 3

    Action of character 1

    Move to (3,1)

    Round of 1

    Action of character 3

    Drive out 1

    Round of 0

    Action of character 2

    Drive out 3

    0

    9

    6

    INVALID

    -1

    Hint

    【数据规模与约定】
    对于80%的数据,不存在不合法事件。
    对于100%的数据,参见输入输出格式中给定的范围与保证。
     
     
     
     
     
     
     

    【分析】

    本题考察基本功,并没有太多的算法上的要求。

    只需要认真阅读题意,谨慎地按照题目所要求的编写代码。

    有几个需要注意的地方:

    1·不能攻击队友。

    2·可以走到原地。

    3·移动中碰到队友是不会把移动力变成0的。

    4·注意死亡的人要移除游戏,死亡后再操作是非法的。

    5·本题的输入有点奇怪。有时会多几个空格。

    code:

    不存在的,我写不出来的

    我的30分代码。。。。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstring>
      5 #define N 200 
      6 using namespace std;
      7 long long dx[4]={0,0,1,-1};
      8 long long dy[4]={1,-1,0,0};
      9 long long group[N],stx[N],sty[N],n,m,C,E,survive[N];
     10 long long check_group(long long x,long long y,long long GROUP){//检查当前步是不是走到了对方的旁边 
     11     for(long long i=1;i<=C;i++){
     12         if(group[i]==GROUP)continue;//自己的人不需要有这些限定 
     13         if(survive[i]==0)continue;//死了 
     14         if(stx[i]==x&&sty[i]==y+1)return 1;//下面是检查相邻的部分 
     15         if(stx[i]==x&&sty[i]==y-1)return 1;
     16         if(stx[i]==x+1&&sty[i]==y)return 1;
     17         if(stx[i]==x-1&&sty[i]==y)return 1;
     18     }
     19     return 0;
     20 }
     21 long long max0=0,G[N][N],dis[N][N];
     22 void check_move(long long now_x,long long now_y,long long final_x,long long final_y,long long rest_MV,long long GROUP){
     23     if(dis[now_x][now_y]!=-1&&dis[now_x][now_y]>=rest_MV)return;
     24 //    cout<<"nowx->"<<now_x<<"  nowy->"<<now_y<<"  finalx->"<<final_x<<"  finaly->"<<final_y<<"  ->rest"<<rest_MV<<'
    ';
     25     if(now_x==final_x&&now_y==final_y){
     26         if(dis[now_x][now_y]!=-1&&dis[now_x][now_y]>=rest_MV)return;
     27         dis[now_x][now_y]=rest_MV;
     28         max0=max(max0,rest_MV);//更新最大值 
     29         return;
     30     }
     31     dis[now_x][now_y]=rest_MV;
     32     if(rest_MV<=max0)return;
     33     if(rest_MV<=0)return ;//如果没能到达终点并且没有步数可以走了就直接不行 
     34     for(long long i=0;i<4;i++){
     35         long long tx=now_x+dx[i],ty=now_y+dy[i];
     36         if(check_group(tx,ty,GROUP)){//如果下一步是对方的旁边就直接削减成0 
     37             if(rest_MV-G[tx][ty]<0)continue;
     38             check_move(tx,ty,final_x,final_y,0,GROUP);
     39             continue;
     40         }
     41         if(tx>n||tx<1||ty<1||ty>m)continue;
     42         check_move(tx,ty,final_x,final_y,rest_MV-G[tx][ty],GROUP);
     43     }
     44 } 
     45 long long ad1[N],ad2[N],hp[N],at[N],mv[N],nowpeople,nowx,nowy,nowgroup;
     46 int main() {
     47     ios::sync_with_stdio(false);
     48     cin>>n>>m>>C>>E;
     49     for(long long i=1; i<=n; i++)
     50         for(long long j=1; j<=m; j++)
     51             cin>>G[i][j];
     52     for(long long i=1; i<=C; i++) {
     53         cin>>hp[i]>>at[i]>>mv[i]>>ad1[i]>>ad2[i]>>stx[i]>>sty[i]>>group[i];
     54         survive[i]=1;//这个人还活着,初始化
     55     }
     56     string k;
     57     while(E--) {
     58         cin>>k;
     59         string zyh;
     60         if(k=="Attack") { //打人但是没有打死的情况
     61             long long ID;
     62             cin>>ID;
     63             if(survive[ID]==0) {
     64                 cout<<"INVALID"<<'
    ';//如果这个人已经死亡了,那么显然是不合法的
     65                 continue;
     66             }
     67             if(group[ID]==group[nowpeople]) { //如果是自己人当然就不合法
     68                 cout<<"INVALID"<<'
    ';
     69                 continue;
     70             }
     71             long long distance=abs(stx[ID]-nowx)+abs(sty[ID]-nowy);
     72             if(distance>ad2[nowpeople]||distance<ad1[nowpeople]) { //如果打不到这个人就代表是不合法的
     73                 cout<<"INVALID"<<'
    ';
     74                 continue;
     75             }
     76             if(hp[ID]-at[nowpeople]<=0) { //如果被打死了,在该状态下是不合法的
     77                 cout<<"INVALID"<<'
    ';
     78                 continue;
     79             }
     80             hp[ID]-=at[nowpeople];//否则就减去这个人的值
     81             cout<<hp[ID]<<'
    ';
     82         } else if(k=="Action") { //代表现在行动的人 ,因为题目描述没有矛盾,所以不做太多判断
     83             cin>>zyh;
     84             cin>>zyh;
     85             long long ID;
     86             cin>>ID;
     87             nowpeople=ID;
     88             nowx=stx[ID];
     89             nowy=sty[ID];
     90         } else if(k=="Round") { //代表该轮中行动的团队 ,题目描述没有矛盾,所以不做判断
     91             cin>>zyh;
     92             long long GR;
     93             cin>>GR;
     94             nowgroup=GR;
     95         } else if(k=="Move") {
     96             long long X=0,Y=0;
     97             cin>>zyh;
     98             cin>>k;
     99             long long flag=0;
    100             for(long long i=0; i<k.size(); i++) {
    101                 if(!isdigit(k[i])&&!flag)continue;
    102                 if(isdigit(k[i])&&(flag==1||flag==0)) {
    103                     flag=1;
    104                     X=(X<<3)+(X<<1)+k[i]-'0';
    105                     continue;
    106                 }
    107                 if(flag==1&&!isdigit(k[i])) {
    108                     flag=2;
    109                     continue;
    110                 }
    111                 if(isdigit(k[i])&&flag==2) {
    112                     Y=(Y<<3)+(Y<<1)+k[i]-'0';
    113                     continue;
    114                 }
    115             }
    116             //cout<<X<<" "<<Y<<endl;/////////////
    117             for(long long i=1; i<=C; i++) {
    118                 if(X==stx[i]&&Y==sty[i]&&group[i]!=group[nowpeople]&&survive[i]) { //如果走到了对方的地方显然是不合法的
    119                     cout<<"INVALID"<<'
    ';
    120                 }
    121             }
    122             max0=-1;
    123             memset(dis,-1,sizeof dis);
    124             check_move(nowx,nowy,X,Y,mv[nowpeople],group[nowpeople]);
    125             if(dis[X][Y]==-1){
    126                 cout<<"INVALID"<<'
    ';
    127                 continue;
    128             }
    129             cout<<dis[X][Y]<<'
    ';
    130             nowx=X,nowy=Y;
    131             stx[nowpeople]=X,sty[nowpeople]=Y;
    132         } else if(k=="Drive") {
    133             cin>>zyh;
    134             long long ID;
    135             cin>>ID;
    136             if(survive[ID]==0) {//这个人已经死亡了,显然是不合法的状态
    137                 cout<<"INVALID"<<'
    ';
    138                 continue;
    139             }
    140             if(group[ID]==group[nowpeople]) { //如果是自己人当然就不合法
    141                 cout<<"INVALID"<<'
    ';
    142                 continue;
    143             }
    144             long long distance=abs(stx[ID]-nowx)+abs(sty[ID]-nowy);
    145             if(distance>ad2[nowpeople]||distance<ad1[nowpeople]) { //如果打不到这个人就代表是不合法的
    146                 cout<<"INVALID"<<'
    ';
    147                 continue;
    148             }
    149             if(hp[ID]-at[nowpeople]>0) { //如果没有被打死,在该状态下是不合法的
    150                 cout<<"INVALID"<<'
    ';
    151                 continue;
    152             }
    153             hp[ID]-=at[nowpeople];//否则就减去这个人的值
    154             survive[ID]=0;//打标记代表这个人已经死亡了
    155             stx[ID]=-9999;//坐标肯定要作废
    156             sty[ID]=-9999;
    157             cout<<hp[ID]<<'
    ';
    158         }
    159     }
    160     return 0;
    161 }

    正解AC的代码:

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<cmath>
      5 using namespace std;
      6 int n,m,C,E,Rnd,id,G[105][105];
      7 int belong[105][105];
      8 int dis[105][105];
      9 struct Character{
     10     int HP,AT,MV,AD1,AD2;
     11     int x,y,GR;
     12     bool DIE;
     13 }p[105];
     14 int getint(){
     15     char c=getchar();int sum=0;
     16     while(!isdigit(c))c=getchar();
     17     while(isdigit(c)){sum=sum*10+c-48;c=getchar();}
     18     return sum;
     19 }
     20 int fx[]={1,-1,0,0};
     21 int fy[]={0,0,1,-1};
     22 void dfs(int x,int y,int mv,bool flag){
     23     if(mv<0)return;
     24     if(flag){
     25         if(belong[x-1][y]&&belong[x-1][y]!=Rnd+1)mv=0;
     26         if(belong[x+1][y]&&belong[x+1][y]!=Rnd+1)mv=0;
     27         if(belong[x][y-1]&&belong[x][y-1]!=Rnd+1)mv=0;
     28         if(belong[x][y+1]&&belong[x][y+1]!=Rnd+1)mv=0;
     29     }
     30     if(dis[x][y]>=mv)return;
     31     dis[x][y]=max(dis[x][y],mv);
     32     int xx,yy;
     33     for(int i=0;i<4;++i){
     34         xx=x+fx[i];yy=y+fy[i];
     35         if(xx>n||xx<1||yy>m||yy<1)continue;
     36         if(belong[xx][yy])continue;
     37         dfs(xx,yy,mv-G[xx][yy],true);
     38     }
     39 }
     40 void Move(int k){
     41     int x=getint(),y=getint();
     42     if(x==p[k].x&&y==p[k].y){
     43         cout<<p[k].MV<<"
    ";
     44         return;
     45     }
     46     if(x>n||x<1||y>m||y<1){
     47         printf("INVALID
    ");
     48         return;
     49     }
     50     memset(dis,-1,sizeof(dis));
     51     dfs(p[k].x,p[k].y,p[k].MV,false);
     52     if(dis[x][y]<0){
     53         printf("INVALID
    ");
     54         return;
     55     }
     56     belong[p[k].x][p[k].y]=0;
     57     belong[x][y]=Rnd+1;
     58     p[k].x=x;p[k].y=y;
     59     cout<<dis[x][y]<<'
    ';
     60 }
     61 void Kill(int x,int y,int type){
     62     if(p[x].GR==p[y].GR||p[x].DIE||p[y].DIE){
     63         printf("INVALID
    ");
     64         return;
     65     }
     66     int dis=abs(p[y].x-p[x].x)+abs(p[y].y-p[x].y);
     67     if(dis>p[x].AD2||dis<p[x].AD1){
     68         printf("INVALID
    ");
     69         return;
     70     }
     71     int rest=p[y].HP-p[x].AT,tp;
     72     if(rest<=0)tp=1;else tp=0;
     73     if(tp!=type){
     74         printf("INVALID
    ");
     75         return;
     76     }
     77     p[y].HP=rest;
     78     cout<<rest<<'
    ';
     79     if(tp){
     80         belong[p[y].x][p[y].y]=0;
     81         p[y].DIE=true;
     82     }
     83 }
     84 int main(){
     85     scanf("%d%d%d%d",&n,&m,&C,&E);
     86     for(int i=1;i<=n;i++)
     87         for(int j=1;j<=m;++j)
     88             scanf("%d",&G[i][j]);
     89     for(int i=1;i<=C;++i){
     90         p[i].HP=getint();p[i].AT=getint();p[i].MV=getint();
     91         p[i].AD1=getint();p[i].AD2=getint();
     92         p[i].x=getint();p[i].y=getint();
     93         p[i].GR=getint();
     94         belong[p[i].x][p[i].y]=p[i].GR+1;
     95     }
     96     char t1,t2;
     97     for(int i=1;i<=E;++i){
     98         t1=getchar();
     99         while(t1!='R'&&t1!='A'&&t1!='M'&&t1!='D')t1=getchar();
    100         switch(t1){
    101             case 'R':Rnd=getint();break;
    102             case 'M':Move(id);break;
    103             case 'D':Kill(id,getint(),1);break;
    104             case 'A':{
    105                 t2=getchar();
    106                 if(t2=='c')id=getint();
    107                 else Kill(id,getint(),0);
    108                 break;
    109             }
    110         }
    111     }
    112     return 0;
    113 }

    我还会来做的,也许是很久很久之后。。。。

    over

  • 相关阅读:
    20+ 个高质量的 Web 按钮设计 PSD 下载
    12 月份 10 个新鲜的 jQuery 插件和教程
    20+ 个有用的 Google 地图的 jQuery 插件和教程
    5个界面效果很炫的JavaScript UI框架
    分享50个使用非比寻常导航菜单设计的创20111227creati意网站
    8 款为 WordPress 文章生成缩略图的插件
    百万级访问量网站的技术准备工作
    推荐8个独特应用的JQuery拖放插件
    开源软件发展史【信息图】
    iOS应用开发应遵循的10条设计原则
  • 原文地址:https://www.cnblogs.com/saionjisekai/p/9760442.html
Copyright © 2020-2023  润新知