CSDN第68期编程竞赛活动经验

1、题目名称:小球游戏

某台有10个小球的游戏机,其设定的规则如下:
每一轮游戏在开始之前会把编号为0到9的小球依次放入从左到右编号也为0到9的10个位置;游戏开始后会快速对调任意两个球的位置若干次,并在结束时要求观众写出从左到右的小球编号顺序,写对就得奖。由于速度很快,所以直接靠观看写对很难。但有个程序员发现这台游戏机其实有一个固定的长度为n的操作序列数据库,每一轮游戏都是随机取一个起始操作序列编号和一个结束操作序列编号(操作序列编号从1到n)并从起始到结束依次执行每个操作序列编号对应的操作,而每个操作序列编号对应的操作就是对该次操作指定的两个编号的位置上的小球进行对调。
现在给出操作序列数据库和每一轮游戏的起始操作序列编号和结束操作序列编号,求每轮游戏结束时从左到右的小球编号顺序。

之前考过的题目,根据字面意思写代码就行了,并没有任何陷阱

#include<stdint.h> 
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 

typedef struct _POS {
    int a;
    int b;
} POS;

int swap(int *datas, int a, int b) {
    int c = datas[a];
    datas[a] = datas[b];
    datas[b] = c;
    return 0;
}

int showdatas(int *datas, int n) {
    for (int i = 0; i < n; i++) {
        if (i == 0) {
            printf("%d", datas[i]);
        } else {
            printf(" %d", datas[i]);
        }
    }
    printf("\n");
    return 0;
}

int resetdatas(int *datas) {
    for (int i = 0; i < 10; i++) {
        datas[i] = i;
    }
    return 0;
}

int main() {
    int n = 0, m = 0;
    scanf(" %d %d", &n, &m);
    POS*pos = (POS*) malloc(sizeof (POS) * n);
    memset(pos, 0, sizeof (POS) * n);
    for (int i = 0; i < n; i++) {
        int a = 0, b = 0;
        scanf(" %d %d", &a, &b);
        pos[i].a = a;
        pos[i].b = b;
    }
    int datas[10] = {0};
    for (int i = 0; i < m; i++) {
        int a = 0, b = 0;
        scanf(" %d %d", &a, &b);
        resetdatas(datas);
        a--;
        b--;
        for (int j = a; j <= b; j++) {
            swap(datas, pos[j].a, pos[j].b);
        }
        showdatas(datas, 10);
    }
    return 0;
}

2、题目名称:王子闯闸门

波斯王子要去救被贾法尔囚禁的公主,但贾法尔用黑魔法在他面前设置了编号从1到n的n道闸门。从王子的位置到1号闸门需要1秒,从n号闸门到公主所在的位置也需要1秒,从p号闸门到p+1或p-1号闸门都需要1秒。 每过1秒钟,王子都必须决定选择前进一道闸门、后退一道闸门或停在原地这三种动作中的一种。当然,王子不能选择移动到关闭状态的闸门而只能选择开启状态的闸门。在王子做出动作选择后,闸门也可能会有关闭和开启的动作,如果王子做完动作后,其所在的闸门在该秒内的动作是从开启变为关闭则他就会被闸门夹死。 现在给出闸门数量n和m个闸门的动作时刻表,求波斯王子需要多少秒才能救出公主。

这边暴力求解,无非就是前进,停止,后退三个行为
这次虽然没超时,但通过率只有40%
都暴力了还没通过,想不通

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 

typedef struct _POS {
    int id;
    int start;
    int end;
} POS;

int max(int a, int b) {
    return a > b ? a : b;
}
//判断当前位置当前时间是否可行 
int checkok(POS*pos, int m, int p, int t) {
    for (int i = 0; i < m; i++) {
        if (pos[i].id != p) {
            continue;
        }
        if (pos[i].start <= t && pos[i].end >= t) {
            return 0;
        }
    }
    return 1;
}
int mint = -1;

int min(int a, int b) {
    if (a == -1) {
        return b;
    }
    return a < b ? a : b;
}

int tryrun(POS*pos, int m, int p, int t, int n) {
    //不能再退了
    if(p==-1){
        return -1;
    }
    //超过当前最佳成绩,不再执行
    if (mint != -1 && t >= mint) {
        return 0;
    }
    //到达目的地了
    if (p == n + 1) {
        //printf("%d",t); 
        mint = min(mint, t);
        return 1;
    }
    if (checkok(pos, m, p + 1, t + 1)) {
        tryrun(pos, m, p + 1, t + 1, n);
    }
    if (checkok(pos, m, p, t + 1)) {
        tryrun(pos, m, p, t + 1, n);
    }
    if (checkok(pos, m, p - 1, t + 1)) {
        tryrun(pos, m, p - 1, t + 1, n);
    }
    return 0;
}

int main() {
    int n, m;
    scanf(" %d %d", &n, &m);
    POS*pos = (POS*) malloc(sizeof (POS) * m);
    memset(pos, 0, sizeof (POS) * m);
    for (int i = 0; i < m; i++) {
        int a, b, c;
        scanf(" %d %d %d", &a, &b, &c);
        pos[i].id = a;
        pos[i].start = b;
        pos[i].end = c;
    }
    tryrun(pos, m, 0, 0, n);
    printf("%d", mint);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值