zoukankan      html  css  js  c++  java
  • 开学第五测

            开学第五测

    T1  期望得分:100;实际得分:70

    锻炼计划(exercise.pas)

    身体是革命的本钱,OIers不要因为紧张的学习和整天在电脑前而忽视了健康问题。小x设计了自己的锻炼计划,但他不知道这个计划是否可行,换句话说如果计划不当可能会让他的体力超支,所以小x请你帮助他。

    一天有1440分钟,所以小x列出的是这一整天第1至第1440分钟的计划。小x的体力用一个整数来表示,他会按照计划表进行锻炼,同时,每分钟小x的体力会自动增加1。如果某一分钟末小x的体力小于等于零,那么可怜的小x就累死了……

    输入(exercise.in)

    第一行是用空格分开的两个整数n,m,分别表示小x的初始体力值和计划的项目数量。

    从第二行开始的m行,每行描述一个锻炼项目:名称、开始时间a、结束时间b、每分钟耗费的体力(用空格分隔),表示此项目从第a分钟初开始,第b分钟末结束。锻炼项目按照开始时间递增顺序给出,不会出现两个项目时间冲突的情况。

    输出(exercise.out)

           输出包括两行,如果计划可行,第一行输出"Accepted",第二行输出这一天过后最后剩余的体力;否则在第一行输出"Runtime Error",第二行输出在第几分钟累死。

    样例

    Input

    Output

    10 1

    Basketball 1 10 1

    Accepted

    1440

    1 1

    Nunchakus 1 1 2

    Runtime Error

    1

    数据范围

    0<n<=2^31-1

    0<=m<=500

    所有中间值的绝对值不会超过2^31-1

    每一个锻炼项目的名称不超过20个字符,其中不含空格。

    思路:简单的模拟(不知道为什么WA掉两个点 qwq)

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    int n, m, sum, ans;
    int l[505], r[505], t[505];
    string s;
    
    int main() {
        //freopen("exercise.in","r",stdin);
        //freopen("exercise.out","w",stdout);
        scanf("%d%d", &n, &m);
        ans = n; sum  = 1440;
        for(int i = 1; i <= m; i++) {
            cin >> s >> l[i] >> r[i] >> t[i];
            sum -= r[i]-l[i]+1;
        }
        for(int i = 1; i <= m; i++)
            for(int j = l[i]; j <= r[i]; j++) {
                ans = ans-t[i]+1;
                if(ans <= 0) {
                    printf("Runtime Error
    %d", j);
                    return 0;
                }
            }
        printf("Accepted
    %d", ans+sum);
        //fclose(stdin); fclose(stdout);
        return 0;
    }
    考场代码,求dalao指正
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define maxn 510
    #define ll long long
    using namespace std;
    ll now, n, falg;
    struct node{
        ll a, b, c;
    }p[maxn];
    ll init() {        //读入优化
        ll x = 0, f = 1; char s = getchar();
        while(s<'0' || s>'9'){ if(s == '-') f = -1; s = getchar(); }
        while(s>='0' && s<='9'){ x = x*10+s-'0'; s = getchar(); }
        return x * f;
    }
    ll Cal(ll x, ll y) {
        if(x%y == 0) return x/y;
        else return x/y+1;
    }
    int main() {
        //freopen("exercise.in","r",stdin);
        //freopen("exercise.out","w",stdout);
        now = init(); n = init();
        for(int i = 1; i <= n; i++) {
            p[i].a = init();
            p[i].b = init();
            p[i].c = init();
        }
        for(int i = 1; i <= n; i++) {
            now += p[i].a-p[i-1].b-1;
            if(now-(p[i].b-p[i].a+1)*p[i].c+p[i].b-p[i].a+1 > 0)
                now = now-(p[i].b-p[i].a+1)*p[i].c+p[i].b-p[i].a+1;
            else {
                now = Cal(now+p[i].a*p[i].c-p[i].a-p[i].c+1, p[i].c-1);
                falg =1 ; break;
            }
        }
        if(falg) cout << "Runtime Error" << endl << now << endl;
        else cout << "Accepted" << endl << now+1440-p[n].b << endl;
        return 0;
    }
    标程

    T2   期望得分:40;实际得分:40

            魔兽争霸(war.pas)

    小x正在销魂地玩魔兽

    他正控制着死亡骑士和n个食尸鬼(编号1~n)去打猎

    死亡骑士有个魔法,叫做“死亡缠绕”,可以给食尸鬼补充HP

    战斗过程中敌人会对食尸鬼实施攻击,食尸鬼的HP会减少

    小x希望随时知道自己部队的情况,即HP值第k多的食尸鬼有多少HP,以便决定如何施放魔法

    请同学们帮助他:)

    小x向你发出3种信号:(下划线在输入数据中表现为空格)

    A_i_a表示敌军向第i个食尸鬼发出了攻击,并使第i个食尸鬼损失了a点HP,如果它的HP<=0,那么这个食尸鬼就死了(Undead也是要死的……)。

    敌军不会攻击一个已死的食尸鬼。

    C_i_a 表示死亡骑士向第i个食尸鬼放出了死亡缠绕,并使其增加了a点HP。

    HP值没有上限。

    死亡骑士不会向一个已死的食尸鬼发出死亡缠绕

    Q_k  表示小x向你发出询问

    输入(war.in)

    第一行,一个正整数 n

    以后n个整数 表示n个食尸鬼的初始HP值

    接着一个正整数m

    以下m行 每行一个小x发出的信号

    输出(war.out)

    对于小x的每个询问,输出HP第k多的食尸鬼有多少HP,如果食尸鬼总数不足k个,输出-1。每个一行数。

    最后一行输出一个数:战斗结束后剩余的食尸鬼数

    样例

    Input Output

    5

    1 2 3

    4 5

    10

    Q 2

    A 4 6

    C 1 4

    Q 2

    A 2 1

    A 3 3

    A 1 3

    Q 4

    C 2 10

    Q 1

    4

    5

    -1

    11

    3

    约定

    40%的数据  n<=3000  m<=5000

    70%的数据  n<=8000  m<=10000

    100%的数据  n<=30000  m<=50000

    90%的数据随机生成

    食尸鬼HP没有上限

    数据保证任意时刻食尸鬼的HP值在longint范围内

    数据保证A和C命令中的食尸鬼是活着的

    输入数据中没有多余空格、换行

    思路:平衡树/伸展树(splay)

    某同学用Trie树A了,然而我不会,用线段树 T 了 6 个点

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define N 30005
    #define LL long long
    using namespace std;
    int n, m, x, y, tot, tat;
    LL a[N];
    char ch;
    struct nond {
        int ll, rr;
        LL hp;
    }tree[4*N];
    bool cmp(LL x, LL y) { return x > y; }
    void build(int now, int l, int r) {
        tree[now].ll = l; tree[now].rr = r;
        if(l == r) {
            scanf("%lld", &tree[now].hp);
            a[++tot] = tree[now].hp;
            return ;
        }
        int mid = (l+r) / 2;
        build(now*2, l, mid);
        build(now*2+1, mid+1, r);
    }
    void change(int now, int x, LL y) {    //被攻击
        if(tree[now].ll == tree[now].rr) {
            for(int i = 1; i <= tot; i++)
                if(a[i] == tree[now].hp) {
                    a[i] -= y;
                    break;
                }
            tree[now].hp -= y;
            if(tree[now].hp <= 0) tat--;
            return ;
        }
        int mid = (tree[now].ll+tree[now].rr) / 2;
        if(x<=mid) change(now*2, x, y);
        else change(now*2+1, x, y);
    }
    void add(int now, int x, LL y) {    //“死亡缠绕”回血
        if(tree[now].ll == tree[now].rr) {
            for(int i = 1; i <= tot; i++)
                if(a[i] == tree[now].hp) {
                    a[i] += y;
                    break;
                }
            tree[now].hp += y;
            return ;
        }
        int mid = (tree[now].ll+tree[now].rr) / 2;
        if(x<=mid) add(now*2, x, y);
        else add(now*2+1, x, y);
    }
    LL find(int k) {    //查询第k大的HP值
        if(tat < k) return -1;
        sort(a+1, a+tot+1, cmp);
        return a[k];
    }
    int main() {
        //freopen("war.in","r",stdin);
        //freopen("war.out","w",stdout);
        scanf("%d", &n);
        build(1, 1, n); tat = n;
        scanf("%d", &m);
        for(int i = 1; i <= m; i++) {
            cin >> ch;
            if(ch == 'A') {    scanf("%d%d", &x, &y); change(1, x, y); }
            if(ch == 'C') {    scanf("%d%d", &x, &y); add(1, x, y); }
            if(ch == 'Q') {    scanf("%d", &x); printf("%lld
    ", find(x)); }
        }
        printf("%lld", tat);    //最后剩余的食尸鬼数量
        //fclose(stdin); fclose(stdout);
        return 0;
    }
    线段树暴力
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define maxn 100010
    #define lc k*2
    #define rc k*2+1
    #define mid (l+r)/2
    using namespace std;
    int n, m, num;
    int a[maxn], b[maxn], c[maxn], s[maxn*4];
    struct node {
        int x, y;
        char z;
    }p[maxn];
    int init() {
        int x = 0, f = 1; char s = getchar();
        while(s<'0' || s>'9') { if(s == '-') f = -1; s = getchar(); }
        while(s>='0' && s<='9') { x = x*10+s-'0'; s = getchar(); }
        return x * f;
    }
    void Insert(int k, int l, int r, int x, int y) {
        if(l==x && r==x) { s[k] += y; return; }
        if(x <= mid) Insert(lc, l, mid, x, y);
        else Insert(rc, mid+1, r, x, y);
        s[k] = s[lc]+s[rc];
    }
    int Query(int k, int l, int r, int x){
        if(l == r) return l;
        if(x > s[lc]) return Query(rc, mid+1, r, x-s[lc]);
        else return Query(lc, l, mid, x);
    }
    int main() {
    //    freopen("war.in","r",stdin);
    //    freopen("war.out","w",stdout);
        n = init();
        for(int i = 1; i <= n; i++) {
            a[i] = init();
            b[i] = a[i]; c[++num] = a[i];
        }
        m = init();
        for(int i = 1; i <= m; i++) {
            cin >> p[i].z; p[i].x = init();
            if(p[i].z != 'Q') p[i].y = init();
            if(p[i].z == 'A') {
                b[p[i].x] -= p[i].y;
                if(b[p[i].x] > 0) c[++num] = b[p[i].x];
            }
            if(p[i].z=='C' && b[p[i].x]>0) {
                b[p[i].x] += p[i].y;
                c[++num] = b[p[i].x];
            }
        }
        sort(c+1, c+1+num);
        int pos, X, Y;
        num = unique(c+1, c+1+num)-c-1;
        for(int i = 1; i <= n;i++) {
            pos = lower_bound(c+1, c+1+num, a[i])-c;
            Insert(1, 1, num, pos, 1);
        }
        for(int i = 1; i <= m; i++) {
            if(p[i].z == 'Q') {
                if(s[1] < p[i].x) { printf("-1
    "); continue; }
                pos = Query(1, 1, num, s[1]-p[i].x+1);
                printf("%d
    ", c[pos]);
            }
            if(p[i].z == 'A') {
                X = a[p[i].x]; a[p[i].x] -= p[i].y;
                pos = lower_bound(c+1, c+1+num, X)-c;
                Insert(1, 1, num, pos, -1);
                Y = a[p[i].x];
                if(Y <= 0) continue;
                pos = lower_bound(c+1, c+1+num, Y)-c;
                Insert(1, 1, num, pos, 1);
            }
            if(p[i].z == 'C') {
                X = a[p[i].x]; if(X <= 0) continue;
                a[p[i].x] += p[i].y;
                pos = lower_bound(c+1, c+1+num, X)-c;
                Insert(1, 1, num, pos, -1);
                Y = a[p[i].x];
                pos = lower_bound(c+1, c+1+num, Y)-c;
                Insert(1, 1, num, pos, 1);
            }
        }
        printf("%d
    ", s[1]);
        return 0;
    }
    标程

    T3  期望得分 = 实际得分 = 0  (此题已暂时弃疗)

            暗黑破坏神(diablo.pas)

    无聊中的小x玩起了Diablo I...

    游戏的主人公有n个魔法

    每个魔法分为若干个等级,第i个魔法有p[i]个等级(不包括0)

    每个魔法的每个等级都有一个效果值,一个j级的i种魔法的效果值为w[i][j]

    魔法升一级需要一本相应的魔法书

    购买魔法书需要金币,第i个魔法的魔法书价格为c[i]

    而小x只有m个金币(好孩子不用修改器)

    你的任务就是帮助小x决定如何购买魔法书才能使所有魔法的效果值之和最大

    开始时所有魔法为0级 效果值为0

    输入(diablo.in)

    第一行 用空格隔开的两个整数n m

    以下n行 描述n个魔法

    第i+1行描述 第i个魔法 格式如下

    c[i] p[i] w[i][1] w[i][2] ... w[i][p[i]]

    输出(diablo.out)

    第一行输出一个整数,即最大效果值。

    以后n行输出你的方案:

    第i+1行有一个整数v[i] 表示你决定把第i个魔法学到v[i]级

    如果有多解 输出花费金币最少的一组

    如果还多解 输出任意一组

    样例

    Input

    Output

    3 10

    1 3 1 2 2

    2 3 2 4 6

    3 3 2 1 10

    11

    1

    0

    3

    约定

    0<n<=100

    0<m<=500

    0<p[i]<=50

    0<c[i]<=10

    保证输入数据和最终结果在longint范围内

    思路:自我感觉是背包,but 标程用的DFS   hua ji

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define maxn 510
    using namespace std;
    int n, m, ans, C, r[20];
    int c[maxn], p[maxn], w[maxn][maxn];
    int init() {
        int x = 0, f = 1; char s = getchar();
        while(s<'0' || s>'9') { if(s == '-') f = -1; s = getchar(); }
        while(s>='0' && s<='9') { x = x*10+s-'0'; s = getchar(); }
        return x * f;
    }
    void Dfs(int s, int x[], int v) {
        if(s > m) return;
        if(v > ans) memcpy(r, x, sizeof(r)), ans = v;
        else if(v==ans && s<C) memcpy(r, x, sizeof(r)), C = s;
        for(int i = 1; i <= n; i++)
            if(x[i] < p[i]) {
                x[i]++; int now = 0;
                for(int j = 1; j <= n; j++) now += w[j][x[j]];
                Dfs(s+c[i], x, now);
                x[i]--;
            }
    }
    int main() {
    //    freopen("diablo.in","r",stdin);
    //    freopen("diablo.out","w",stdout);
        n = init(); m = init();
        for(int i = 1; i <= n; i++) {
            c[i] = init(); p[i] = init();
            for(int j = 1; j <= p[i]; j++)
                w[i][j] = init();
        }
        int x[20] = {0};
        Dfs(0, x, 0);
        printf("%d
    ", ans);
        for(int i = 1; i <= n; i++) printf("%d
    ", r[i]);
        return 0;
    }
    标程
  • 相关阅读:
    关于16位的OS尝试(2)
    关于16位的OS尝试(2)
    键盘幽灵程序源代码
    socks5协议转http协议源码
    溢出专题(二) widechar的字符串缓冲溢出攻击技术
    超强:bat写的exploit
    键盘幽灵程序源代码
    超强:bat写的exploit
    socks5协议转http协议源码
    高质量C /C编程指南第3章 命名法例
  • 原文地址:https://www.cnblogs.com/v-vip/p/8952670.html
Copyright © 2011-2022 走看看