[hihocoder1392]ACM/ICPC Beijing

描述

Rainbow loves to play kinds of War Chess games. There are many famous War Chess games such as “Biography of Cao Cao”, “Anecdotes of Wagang Mountain”, etc. In this problem, let’s consider a much simpler version of War Chess games. The game is based on the following features:

MAP

The map is a rectangular area which consists of N rows and M columns. The cells in the rectangular area have various landforms like plain, woods, hill, river, snowfield, etc. Specifically, each cell (i,j) is assigned an integer of moving property Gi,j, which makes influence on going across it.

CHARACTER

A character can be regarded as a person standing in a cell of the map. Each character has life HP, attacking ability AT, moving ability MV and attacking distance range [AD1,AD2]. Characters are divided into two groups. Group 0 is controlled by the player and group 1 is controlled by the system.

A character can attack a character from the opposite group if the Manhattan distance between them is in the attacker’s attacking distance range (inclusive). When a character p is attacked by enemy q, its life HPp will be minus by ATq. A character is driven out of the map immediately when its HP becomes 0 or negative.

Each character can occupy a cell or move on the map. Several rules specify the position and moving limits of them:

OCCUPATION

Initially, characters are generated in different cells. They occupy their own cell separately. A character cannot move when another one is moving.

Once a character starts to move, it will lose occupation of its current standing cell. When the character stops moving, it will gain the occupation of the cell it is standing in.

STEP

A move consists of several steps. Each step, one can walk from a cell to an adjacent cell sharing an edge (up, down, left or right). A step walking to a cell occupied by the other character is invalid.

When it steps from a cell (i,j) to a cell (x,y), its moving ability MV will be minus by Gx,y. Moving steps which make MV become negative are invalid. After a valid step, if the current cell is beside (sharing an edge with) someone of the opposite group, the MV of a character will become 0.

A character’s MV recovers to the original value immediately when it gains occupation of a cell.

The set of cells, able to be reached by valid steps and stopped at in a move, is called a character’s moving range. Staying at the original cell is also valid and should be counted into the moving range.

The process of the game contains several rounds. In each round, the player’s group acts first and the system’s group acts next. For each group, the characters of the group act by turns. In each action, a character first moves to a cell in its moving range, then attacks a character of the opposite group in its attacking distance range or do nothing. When all the characters of a group are driven out of the map, the group loses the game and the opposite group wins.

Rainbow has just got some logs of a game and wants to watch the game. Help him to recover the game process.

做法

  1. 十分明显的模拟题,但是奇怪的是比赛的时候没有很多人去做这一题。
  2. 按照题目的要求更改当前的移动的属组和移动的对象
  3. 最麻烦的是在move的时候,我们预先将点分成3种,分别是可以进入的点,有士兵占据的点和敌军的旁边的点。枚举所有士兵的位置进行预处理,然后再进行BFS。很快就解决了。
  4. 其他的操作只要按照题目来写就好了。没啥难度。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;

#define MAXN 105
#define INF 0x3f3f3f3f

struct people{
    int hp,at,mt,ad1,ad2,gp;
    int x,y;
    bool dead;
}peopleList[MAXN];

const int mvx[4]={0,0,1,-1};
const int mvy[4]={1,-1,0,0};
int n,m,c,e;
int grid[MAXN][MAXN];
int curID,curG;

int Mdis(int a,int b)
{
    return abs(peopleList[a].x-peopleList[b].x)+abs(peopleList[a].y-peopleList[b].y);
}

void Bfs(int curx,int cury)
{
    int state[MAXN][MAXN];
    int d[MAXN][MAXN];
    int i,j;
    queue<int>Q;

    memset(state,0,sizeof(state));
    memset(d,INF,sizeof(d));

    d[peopleList[curID].x][peopleList[curID].y]=0;
    Q.push(peopleList[curID].x);
    Q.push(peopleList[curID].y);

    for(i=1;i<=c;i++){
        if(peopleList[i].dead)continue;
        state[peopleList[i].x][peopleList[i].y]=1;
        if(peopleList[i].gp!=curG){
            for(j=0;j<4;j++){
                if(peopleList[i].x+mvx[j]>n||peopleList[i].y+mvy[j]>m||peopleList[i].x+mvx[j]<=0||peopleList[i].y+mvy[j]<=0||state[peopleList[i].x+mvx[j]][peopleList[i].y+mvy[j]]==1)
                    continue;
                else
                    state[peopleList[i].x+mvx[j]][peopleList[i].y+mvy[j]]=2;
            }
        }
    }

    while(!Q.empty()){
        int xx = Q.front();Q.pop();
        int yy = Q.front();Q.pop();
        //cout << xx << yy << endl;

        for(i=0;i<4;i++){
            int xxx = xx+mvx[i];
            int yyy = yy+mvy[i];
            if(xxx<=0||xxx>n||yyy<=0||yyy>m||state[xxx][yyy]==1||grid[xxx][yyy]+d[xx][yy]>peopleList[curID].mt)
                continue;
            else if(state[xxx][yyy]==2)
                d[xxx][yyy]=peopleList[curID].mt;
            else if(d[xxx][yyy]>d[xx][yy]+grid[xxx][yyy]){
                d[xxx][yyy] = d[xx][yy] + grid[xxx][yyy];
                Q.push(xxx);
                Q.push(yyy);
            }
        }
    }


    if(d[curx][cury]<INF){
        printf("%d\n",peopleList[curID].mt-d[curx][cury]);
        peopleList[curID].x = curx;
        peopleList[curID].y = cury;
    }
    else
        printf("INVALID\n");

    return;
}


void attack()
{
    int tar;
    scanf("%d",&tar);
    if(!peopleList[tar].dead&&!peopleList[curID].dead&&(peopleList[tar].gp != peopleList[curID].gp)&&Mdis(tar,curID)>=peopleList[curID].ad1&&Mdis(tar,curID)<=peopleList[curID].ad2){
        if(peopleList[curID].at<peopleList[tar].hp){
            peopleList[tar].hp -= peopleList[curID].at;
            printf("%d\n",peopleList[tar].hp);
        }
        else{
            printf("INVALID\n");
        }
    }
    else{
        printf("INVALID\n");
    }
    return;
}

void drive()
{
    int tar;
    char s[10];
    scanf("%s%d",s,&tar);
    if(!peopleList[tar].dead&&!peopleList[curID].dead&&(peopleList[tar].gp != peopleList[curID].gp)&&Mdis(tar,curID)>=peopleList[curID].ad1&&Mdis(tar,curID)<=peopleList[curID].ad2){
        if(peopleList[curID].at>=peopleList[tar].hp){
            peopleList[tar].hp -= peopleList[curID].at;
            peopleList[tar].dead = true;
            printf("%d\n",peopleList[tar].hp);
        }
        else{
            printf("INVALID\n");
        }
    }
    else{
        printf("INVALID\n");
    }
    return;
}

void round()
{
    char str[10];
    scanf("%s%d",str,&curG);
}

void action()
{
    char str1[10],str2[10];
    scanf("%s%s%d",str1,str2,&curID);
    if(peopleList[curID].dead || peopleList[curID].gp != curG)
        printf("INVALID\n");
}

void move()
{
    int xx,yy;
    char s[10];
    scanf("%s (%d,%d)",s,&xx,&yy);
    //sscanf(s2,"%d %d",&xx,&yy);
    //cout << xx << yy << endl;
    if(peopleList[curID].dead){
        printf("INVALID\n");
        return;
    }
    Bfs(xx,yy);
}

int main()
{
    freopen("input","r",stdin);
    int i,j;
    char str[10];
    while(scanf("%d%d%d%d",&n,&m,&c,&e)!=EOF){
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++){
                scanf("%d",&grid[i][j]);
            }
        }

        for(i=1;i<=c;i++){
            scanf("%d%d%d%d%d%d%d%d",&peopleList[i].hp,&peopleList[i].at,&peopleList[i].mt,&peopleList[i].ad1,&peopleList[i].ad2,&peopleList[i].x,&peopleList[i].y,&peopleList[i].gp);
            peopleList[i].dead = false;
        }

        for(i=0;i<e;i++){
            scanf("%s",str);
            if(strcmp(str,"Round")==0)round();
            else if(strcmp(str,"Move")==0)move();
            else if(strcmp(str,"Action")==0)action();
            else if(strcmp(str,"Drive")==0)drive();
            else attack();
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值