#23. 战棋游戏——Yucai OJ第17次测试

问题描述

Rainbow 擅长玩战棋类游戏。著名的战棋游戏有很多,例如《曹操传》、《瓦岗 山异闻录》等。在本题中,我们考虑战棋游戏的一个简单版本,基于以下规则:

  • 地图

地图是一个 N 行 M 列的矩阵,矩阵中的不同位置有不同的地形,例如平 原、树林、山地、河流、雪原等。在这里,我们给矩阵中的每个位置(i,j(i,j) 规 定一个正整数i,j  Gi,j 这个整数会对在矩阵中的移动产生影响。

  • 角色

每个角色均可被视作位于矩阵中某个位置上的人物。每个角色具有生命值 HHP , 攻击力AAT , 移动力MMV 和攻击范围[A,A[AD1,AD2] 。角色被分为两个阵营, 第 0 阵营被玩家控制,第 1 阵营被系统控制。 当两个不同阵营的角色 p 和 q 的曼哈顿距离处于 p 的攻击范围内(包含端 点)时,p 可以攻击 q 。若 q 被 p 攻击,则 q 的生命值被减去 p 的攻击力。 当一个角色的生命值 ≤0 时,它将立即被移除出地图,离开游戏。 每个角色均占领地图上的一个位置,并且可以在地图上移动,遵循以下规则:

  • 占领

最初,每个角色在地图的不同位置生成。他们各自占领自己所在的位置。 当一个角色在移动时,其它角色均不能移动。 一个角色开始移动前失去对所在位置的占领权,停止移动时获得所在位置 的占领权。

  • “移动”与“步”

一次移动由若干步组成。在每一步中,一个角色可以从当前位置走向四个 方向上相邻的位置,但不能走到被其它角色占领的位置上。

当一个角色从(i,j(i,j) 走到 (x,y(x,y) 时, 它的移动力会被扣除 x,y  Gx,y 。使得移动力变为负数的“步”是不合法的。在合法的一“步”完成后,若该角色正 处于与对方阵营某个角色相邻(四个方向)的位置上,则该角色的移动力 立即被减为 0,换句话说,他将不能再走另外一步。 当一次“移动”结束后,角色的移动力恢复为初始值。

能被一个角色通过若干合法“步”到达的位置集合称为该角色的移动范围。停留在原地也是合法的,故也被算入移动范围。

游戏的过程由若干轮组成,每轮玩家阵营先行动,系统阵营后行动。对于每个 阵营,该阵营的所有角色轮流行动。在每次行动中,一个角色先移动到移动范围 内的任意一个位置,然后可能会攻击对方阵营的一个角色(或什么也不做)。 当 一个阵营的所有角色均被移除出地图时,另外一个阵营获胜。 Rainbow 得到了一份游戏日志,请帮他复原这个游戏的过程。

输入格式

第一行 4 个整数 N,M,C,E(1N,M100,2Cmin(N×M,100),1E3000N,M,C,E(1≤N,M≤100,2≤C≤min(N×M,100),1≤E≤3000) , 表示地图行数、列数、角色数、日志事件数。 接下来N 行每行M 个整数 i,(1i,10 Gi,j(1≤Gi,j≤102) 。

接下来 C 行每行 8 个整数 HP,AT,MV,A,A,S,S,GR(1HP,AT,MV10 HP,AT,MV,AD1,AD2,STx,STy,GR(1≤HP,AT,MV≤103, 1AA20,1SN,1SM,0GR11≤AD1≤AD2≤20,1≤STx≤N,1≤STy≤M,0≤GR≤1) , 表示角色的 5 个属性以及初始位置、所属阵营。

接下来 E 行描述日志中的事件,每个事件都是以下格式之一: Round of GR – 阵营 GGR 行动回合开始。 Action of character ID – 角色 IID 行动开始。 Move to (x,y) – 当前行动角色通过若干步移动到 (x,y(x,y) 。 Attack ID – 当前行动角色攻击角色 IID 但是角色 IID 在攻击后未被移除。 Drive out ID – 当前行动角色攻击角色 IID 并造成 IID 被移出游戏。 在事件中, 1xN,1yM,1IDC,0GR1≤x≤N,1≤y≤M,1≤ID≤C,0≤GR≤1 。 行列标号从 1 开始,每个阵营初始至少拥有 1 个角色。

输出格式

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

样例输入

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

数据规模与约定

对于 8080% 的数据,不存在不合法事件。

对于 100100% 的数据,参见输入输出格式中给定的范围与保证。 

题解

暴力???(应该吧)

  1 #include<iostream>
  2 #include<queue>
  3 #include<stack>
  4 #include<cstdio>
  5 #include<cstring>
  6 #include<algorithm>
  7 using namespace std;
  8 const int Max=111;
  9 int x0[4]={0,1,0,-1},y0[4]={1,0,-1,0};
 10 int map[Max][Max],G[Max][Max],DT[Max][Max],IN[Max][Max],n,m,c,e,gr,character;
 11 char Event[30];
 12 queue <int> Qx,Qy;
 13 struct Data{
 14     int HP,AT,MV,AD1,AD2,X,Y,GR;
 15 }Character[Max];
 16 int Level(char Event[30]){
 17     if(Event[0]=='R'){
 18         return 1;
 19     }
 20     if(Event[0]=='A' && Event[1]=='c'){
 21         return 2;
 22     }
 23     if(Event[0]=='M'){
 24         return 3;
 25     }
 26     if(Event[0]=='D'){
 27         return 4;
 28     }
 29     return 5;
 30 }
 31 int CloseEnemy(int x,int y){
 32     return (map[x-1][y]==1-gr) || (map[x+1][y]==1-gr) || (map[x][y-1]==1-gr) || (map[x][y+1]==1-gr);
 33 }
 34 void Move(int Ex,int Ey){
 35     if(Character[character].HP<0){
 36         printf("INVALID\n");
 37         return;
 38     }
 39     for(int i=1;i<=n;i++){
 40         for(int j=1;j<=m;j++){
 41             DT[i][j]=1<<30;
 42             IN[i][j]=0;
 43         }
 44     }
 45     int Sx=Character[character].X,Sy=Character[character].Y;    
 46     for(Qx.push(Sx),Qy.push(Sy),DT[Sx][Sy]=0,IN[Sx][Sy]=0;!Qx.empty();Qx.pop(),Qy.pop()){
 47         int x=Qx.front(),y=Qy.front(); IN[x][y]=0;
 48         for(int i=0;i<4;i++){
 49             int xx=x+x0[i],yy=y+y0[i];
 50             if(xx<1 || xx>n || yy<1 || yy>m || map[xx][yy]!=-1){
 51                 continue;
 52             }
 53             if(CloseEnemy(xx,yy)){
 54                 DT[xx][yy]=max(Character[character].MV,DT[x][y]+G[xx][yy]);
 55             }else if(DT[x][y]+G[xx][yy]<DT[xx][yy]){
 56                 DT[xx][yy]=DT[x][y]+G[xx][yy];
 57                 if(IN[xx][yy] || DT[xx][yy]>=Character[character].MV){
 58                     continue;
 59                 }
 60                 Qx.push(xx); Qy.push(yy); IN[xx][yy]=1;
 61             }
 62         }
 63     }
 64     if(DT[Ex][Ey]>Character[character].MV){
 65         printf("INVALID\n");
 66     }else{
 67         printf("%d\n",Character[character].MV-DT[Ex][Ey]);
 68         map[Sx][Sy]=-1; 
 69         map[Ex][Ey]=gr; 
 70         Character[character].X=Ex; 
 71         Character[character].Y=Ey;
 72     }
 73 
 74 }
 75 void Drive(int Enemy){
 76     if(Character[character].HP<0){
 77         printf("INVALID\n");
 78         return;
 79     }
 80     int dist=abs(Character[character].X-Character[Enemy].X)+abs(Character[character].Y-Character[Enemy].Y);
 81     if(Character[Enemy].HP>0 && dist>=Character[character].AD1 && dist<=Character[character].AD2 && Character[character].AT>=Character[Enemy].HP){
 82         printf("%d\n",Character[Enemy].HP-=Character[character].AT);
 83         map[Character[Enemy].X][Character[Enemy].Y]=-1;
 84     }else{
 85         printf("INVALID\n");
 86     }
 87 }
 88 void Attack(int Enemy){
 89     if(Character[character].HP<0 || Character[Enemy].GR==gr){
 90         printf("INVALID\n");
 91         return ;
 92     }
 93     int dist=abs(Character[character].X-Character[Enemy].X)+abs(Character[character].Y-Character[Enemy].Y);
 94     if(Character[Enemy].HP>0 && dist>=Character[character].AD1 && dist<=Character[character].AD2 && Character[character].AT<Character[Enemy].HP){
 95         printf("%d\n",Character[Enemy].HP-=Character[character].AT);
 96     }else{
 97         printf("INVALID\n");
 98     }
 99     return ;
100 }
101 int main(){
102     scanf("%d%d%d%d",&n,&m,&c,&e);
103     for(int i=1;i<=n;i++){
104         for(int j=1;j<=m;j++){
105             scanf("%d",&G[i][j]);
106         }
107     }
108     memset(map,-1,sizeof(map));
109     for(int i=1;i<=c;i++){
110         scanf("%d%d%d%d%d%d%d%d\n",&Character[i].HP,&Character[i].AT,&Character[i].MV,&Character[i].AD1,&Character[i].AD2,&Character[i].X,&Character[i].Y,&Character[i].GR);
111         map[Character[i].X][Character[i].Y]=Character[i].GR;
112     }
113     for(int i=1;i<=e;i++){
114         gets(Event);
115         int level=Level(Event);
116         if(level==1){
117             gr=Event[9]-'0';
118         }
119         if(level==2){
120             character=0;
121             for(int j=20;Event[j]>='0' && Event[j]<='9';j++){
122                 character=character*10+Event[j]-'0';
123             }
124         }
125         if(level==3){
126             int j,Ey=0,Ex=0;
127             for(j=9;Event[j]>='0' && Event[j]<='9';j++){
128                 Ex=Ex*10+Event[j]-'0';
129             }
130             for(j++;Event[j]>='0' && Event[j]<='9';j++){
131                 Ey=Ey*10+Event[j]-'0';
132             }
133             Move(Ex,Ey);
134         }
135         if (level==4){
136             int Enemy=0;
137             for(int j=10;Event[j]>='0' && Event[j]<='9';j++){
138                 Enemy=Enemy*10+Event[j]-'0';
139             }
140             Drive(Enemy);
141         }
142         if(level==5){
143             int Enemy=0;
144             for(int j=7;Event[j]>='0' && Event[j]<='9';j++){
145                 Enemy=Enemy*10+Event[j]-'0';
146             }
147             Attack(Enemy);
148         }
149     }
150     return 0;
151 }
标程???

 

转载于:https://www.cnblogs.com/VOCAOID/p/9560929.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
后台采用apache服务器下的cgi处理c语言做微信小程序后台逻辑的脚本映射。PC端的服务器和客户端都是基于c语言写的。采用mysql数据库进行用户数据和聊天记录的存储。.zip C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。下面详细介绍C语言的基本概念和语法。 1. 变量和数据类型 在C语言中,变量用于存储数据,数据类型用于定义变量的类型和范围。C语言支持多种数据类型,包括基本数据类型(如int、float、char等)和复合数据类型(如结构体、联合等)。 2. 运算符 C语言中常用的运算符包括算术运算符(如+、、、/等)、关系运算符(如==、!=、、=、<、<=等)、逻辑运算符(如&&、||、!等)。此外,还有位运算符(如&、|、^等)和指针运算符(如、等)。 3. 控制结构 C语言中常用的控制结构包括if语句、循环语句(如for、while等)和switch语句。通过这些控制结构,可以实现程序的分支、循环和多路选择等功能。 4. 函数 函数是C语言中用于封装代码的单元,可以实现代码的复用和模块化。C语言中定义函数使用关键字“void”或返回值类型(如int、float等),并通过“{”和“}”括起来的代码块来实现函数的功能。 5. 指针 指针是C语言中用于存储变量地址的变量。通过指针,可以实现对内存的间接访问和修改。C语言中定义指针使用星号()符号,指向数组、字符串和结构体等数据结构时,还需要注意数组名和字符串常量的特殊性质。 6. 数组和字符串 数组是C语言中用于存储同类型数据的结构,可以通过索引访问和修改数组中的元素。字符串是C语言中用于存储文本数据的特殊类型,通常以字符串常量的形式出现,用双引号("...")括起来,末尾自动添加'\0'字符。 7. 结构体和联合 结构体和联合是C语言中用于存储不同类型数据的复合数据类型。结构体由多个成员组成,每个成员可以是不同的数据类型;联合由多个变量组成,它们共用同一块内存空间。通过结构体和联合,可以实现数据的封装和抽象。 8. 文件操作 C语言中通过文件操作函数(如fopen、fclose、fread、fwrite等)实现对文件的读写操作。文件操作函数通常返回文件指针,用于表示打开的文件。通过文件指针,可以进行文件的定位、读写等操作。 总之,C语言是一种功能强大、灵活高效的编程语言,广泛应用于各种领域。掌握C语言的基本语法和数据结构,可以为编程学习和实践打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值