CCF-CSP 201609 总结

第一题

简单求最值

int main() {
    int n;
    int list[1010];
    scanf("%d", &n);
    int max = -1;
    for (int i = 0; i < n; i++) {
        scanf("%d", &list[i]);
        int curr = abs(list[i] - list[i - 1]);
        if (i > 0 && curr > max)
            max = curr;
    }
    cout << max;
}

第二题

简单模拟,但是不知道为什么只有90分,10分错误没找到原因;

90分代码如下:

int seat[21][6], choosed[21][6], remains[21];

//找到l行的前num个空位置并打印其座位号,最后换行
void getseat(int l, int num) {
    int k = 1;
    while (num) {
        if (!choosed[l][k]) {
            choosed[l][k] = 1;
            num--;
            printf("%d ", seat[l][k]);
        }
        k++;
    }
}

int main() 
{
    int k = 1;
    for (int i = 1; i <= 20; i++) {
        for (int j = 1; j <= 5; j++) {
            seat[i][j] = k++;
        }
    }
    fill(remains + 1, remains + 21, 5);
    int n, curr, i, j;
    scanf("%d", &n);
    for (i = 0; i < n; i++) {
        scanf("%d", &curr);
        for (j = 1; j <= 20; j++) {
            if (remains[j] >= curr) {
                remains[j] -= curr;
                getseat(j, curr);
                printf("\n");
                break;
            }
        }
        if (j == 21) {
            for (j = 1; j <= 20; j++) {
                while (remains[j] && curr) {
                    remains[j]--, curr--;
                    getseat(j, 1);
                }
                printf("\n");
            }
        }
    }
}

第三题

比较复杂的模拟,但是并不难,70分代码,太长了不想检查了。。

70分代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <map>

using namespace std;

struct sc {
    int hp;
    int att;
};
map<string, int> order = {
    {"summon", 1}, {"attack", 2},{"end",0}
};

sc arena[3][8];
bool havesc[3][8];
//玩家player 在pos位置放置一个随从,pos位置及其右边的随从向右移动;
int Other(int dirc) {
    if (dirc == 1)
        return 2;
    else
        return 1;
}
void getPos(int player, int pos, sc x) {
    //如果当前放置位置为空则直接放置
    if (!havesc[player][pos]) {
        int r = pos;
        while (!havesc[player][r] && r > 0) 
            r--;
        havesc[player][r + 1] = true;
        arena[player][r + 1] = x;
    }
    else {
    //如果当前位置有人了,则用r向右边查找,直至找到第一个为空的位置
        int r = pos;
        while (havesc[player][r]) r++;
        havesc[player][r] = true;
        for (int i = r; i > pos; i--) {
            arena[player][i] = arena[player][i - 1];
        }
        arena[player][pos] = x;
    }
}

void dealDead(int dirc,int a) {
    int pos = a;
    while (havesc[dirc][pos]) pos++;
    pos--;
    for (int i = a; i < pos ; i++) {
        arena[dirc][i] = arena[dirc][i + 1];
    }
    havesc[dirc][pos] = 0;
}

void GetAttack(int dirc,int a,int d) {
    //如果攻击方生命值不够,则被移除
    arena[dirc][a].hp -= arena[Other(dirc)][d].att;
    //if (arena[dirc][a].hp <= 0)    havesc[dirc][a] = 0;
    if (arena[dirc][a].hp <= 0) dealDead(dirc, a);
    //如果防守方生命值不够,则被移除
    arena[Other(dirc)][d].hp -= arena[dirc][a].att;
    //if (arena[Other(dirc)][d].hp <= 0)    havesc[Other(dirc)][d] = 0;
    if (arena[Other(dirc)][d].hp <= 0) dealDead(Other(dirc), d);
}

void GAMEOVER(int p) {
    //如果没分出胜负
    if (p == 0) {
        printf("0\n");
    }
    //如果1号先手玩家噶了
    else if (p == 1) {
        printf("1\n");
    }
    //如果2号后手玩家噶了
    else if (p == 2) {
        printf("-1\n");
    }

    //统计玩家随从存活数量
    int cnt1 = 0, cnt2 = 0;
    for (int i = 1; i <= 7; i++) {
        if (havesc[1][i]) cnt1++;
        if (havesc[2][i]) cnt2++;
    }
    //打印1号玩家数据
    printf("%d\n%d ",arena[1][0].hp, cnt1);
    for (int i = 1; i <= 7; i++) {
        if (havesc[1][i]) {
            printf("%d ", arena[1][i].hp);
        }
    }
    printf("\n");

    //打印2号玩家数据
    printf("%d\n%d ",arena[2][0].hp, cnt2);
    for (int i = 1; i <= 7; i++) {
        if (havesc[2][i]) {
            printf("%d ", arena[2][i].hp);
        }
    }
}

int main() {
    //dirc 表示当前先手的玩家,1为1号玩家,2为2号玩家
    int n, dirc = 1;
    scanf("%d", &n);
    //初始化英雄生命值
    arena[1][0].hp = 30, arena[2][0].hp = 30;
    arena[1][0].att = 0, arena[2][0].att = 0;
    for (int i = 0; i < n; i++) {
        string s;
        cin >> s;
        //end命令,交换回合
        if (order[s] == 0) {
            dirc = Other(dirc);
        }
        //召唤命令
        else if (order[s] == 1) {
            int p;
            sc x;
            scanf("%d%d%d", &p, &x.att, &x.hp);
            getPos(dirc, p, x);
        }
        //攻击命令
        else if (order[s] == 2) {
            int a, d;
            scanf("%d%d", &a, &d);
            GetAttack(dirc, a, d);
            if (arena[1][0].hp <= 0) {
                GAMEOVER(1);
                return 0;
            }
            else if (arena[2][0].hp <= 0) {
                GAMEOVER(2);
                return 0;
            }
        }
    }
    GAMEOVER(0);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值