zoukankan      html  css  js  c++  java
  • 8 November in 614

    我开始看心灵鸡汤了……

    每当在书中读及那些卑微的努力,都觉得感动且受震撼。也许每个人在发出属于自己的光芒之前,都经历了无数的煎熬,漫长的黑夜,无尽的孤独,甚至不断的嘲讽和否定,但好在那些踮脚的少年,最后都得到了自己想要的一切。

    某乎

    学习信息竞赛对我来说,是一份美妙而充实的身心体验。随着一份份代码的 AC,雀跃的心灵是决不同于其他方面的。文化课的学习生活对我是一种美食的享受,而信息竞赛则更像是一次海天盛宴,让人充满前进和追求远方的动力与勇气。学习算法是快乐的,因为人本不是为使自己更加疲惫而制造工具的,而是简化工序,使用各种工具让自己的生活更加简单便捷。算法竞赛是追求化繁为简的,是追求高效和正确的,这也正是对待生活的良好态度。几年下来,随着知识和阅历的增加,生活也变得更加充满意义,对时间的把握能力更强了,这是信息竞赛带给我的人生财富。愿我在这条路上走得再远一些,以更好的姿态追求无尽的前方。

    今明两天再总结总结,总结经验和教训,把简单题再扎实一下。不要好高骛远了,毕竟我学了不少复杂的知识 NOIP 都用不上。(除了模拟退火真贪心啊……)

    Contest

    已经写了好几天水题赛了,但是还是不长进啊……

    A. ssoj2997 删除(removal)

    开始给你 (N) 个元素的数组(下标从 1 开始),数组里的数是 (1,2,3,…,N),然后执行 (D) 次删除操作。每次删除操作给一个区间 ([lo, hi]),要求删除下标位置从 (lo)(hi) 的数,数组里的数据个数会减少 (hi-lo+1) 个。

    例如,(N=8),第 1 次删除操作区间是 ([3,4]),结果为 “(1,2,5,6,7,8)”;第 2 次删除操作区间是 ([4,5]),结果为 “(1,2,5,8)”。

    最后,输出第 (M) 位的数字是什么。如果剩余的数不够 (M) 个,输出 (-1)

    (1le Mle Nle 2 imes10^9,1le Dle 50)

    显然,正向做题不可行,因为操作区间太大。

    考虑逆向。对于最后问的第 (M) 个数,它前面后面有不少数已被删去,不过后面的数对答案没有贡献,前面的删除区间不可能覆盖到 (M)(想一想,为什么?)。

    每一次 (M) 前面的区间被删除,(M) 的位置相当于向前移动。所以逆向把 (M) 前的区间还原回去就可以了。

    #include <cstdio>
     
    int T, n, m, d, l[53], r[53];
     
    int main() {
        scanf("%d", &T);
        while (T--) {
            scanf("%d%d%d", &n, &m, &d);
            for (int i=1; i<=d; ++i) scanf("%d-%d", &l[i], &r[i]);
            for (int i=d; i; --i) if (l[i]<=m) m+=r[i]-l[i]+1;
            printf("%d
    ", m>n?-1:m);
        }
        return 0;
    }
    

    B. ssoj2998 jyt 的崇拜者(sequence)

    (n) 个元素的整数序列 (A),要求修改成单调不减的序列 (B),代价 (max{|A_i-B_i|,1≤i≤n})。求最小代价。

    之前做过,保证 (B_i) 一定大于等于 (A_i) 即可。

    #include <cstdio>
    #include <algorithm>
    using namespace std;
     
    int n, A, B, ans;
     
    int main() {
        scanf("%d", &n);
        for (int i=1; i<=n; ++i) scanf("%d", &A),
            B=max(B, A), ans=max(ans, (B-A+1)>>1);
        printf("%d
    ", ans);
        return 0;
    }
    

    考场上为什么 WA 了呢?!!!考场上想太多了!

    是啊,水题就不要多想,要相信直觉!

    C. ssoj2984 蚂蚁 ants

    Zkp 从小喜欢观察生物。这一天,他发现台阶上有 (n) 只蚂蚁排成一排。台阶可以视为长度无限的数轴,第 (i) 只蚂蚁的位置为 (p_i),有的朝左走有的朝右走。每只蚂蚁每秒钟都可以走 1 个长度单位,当两只蚂蚁面对着相遇的时候,他们会立即调转方向,以原来的速度向新方向继续前进。现在 zkp 想知道 (T) 秒过后,每只蚂蚁将会移动到哪里。

    这个是蓝书P9(UVa 10881)上的内容。怎能不 A?

    #include <cstdio>
    #include <algorithm>
    using namespace std;
     
    int n, T;
     
    struct node {int x, d, id; } G[200005];
     
    bool cmp1(const node& a, const node& b) {return a.x < b.x || a.x==b.x && a.d<b.d; }
    bool cmp2(const node& a, const node& b) {return a.id < b.id; }
     
    int main() {
        scanf("%d%d", &n, &T);
        for (int i=1; i<=n; ++i) scanf("%d%d", &G[i].x, &G[i].d),
            G[i].id=i, G[i+n].x=G[i].x+(G[i].d?T:-T), G[i+n].d=G[i].d;
        sort(G+n+1, G+(n<<1)+1, cmp1);
        sort(G+1, G+n+1, cmp1); for (int i=1; i<=n; ++i) G[i].x=i;
        sort(G+1, G+n+1, cmp2);
        for (int i=1; i<=n; ++i) printf("%d ", G[G[i].x+n].x);
        return 0;
    }
    

    D. ssoj3149 饥饿的狐狸

    到你的宠物狐狸的晚餐时间啦!他的晚餐包含 (N) 块饼干,第 (i) 块饼干的温度是 (T_i) 摄氏度。同时,在晚餐中还包含了一大盘 (W) 摄氏度的水。

    在喝了一口水之后,你的狐狸开始吃饭了。每当他吃一块饼干时,这块饼干的美味度为当前饼干与吃 / 喝的前一样食物(包括饼干和水)温度的差的绝对值。它可以在任意时间喝水(保证水喝不完),或按任意顺序吃饼干。

    最后狐狸获得的美味值为它吃下的每块饼干的美味度之和。请求出狐狸获得的最小和最大的美味值。

    要得到最小美味值,一种可行的方案是,狐狸先喝水,然后吃第一块饼干,再吃第三块饼干,接着喝水,最后吃下第二块饼干,这样做,它所感受到的温度分别为 (20,18,18,20,25) 摄氏度,总的美味度为 (2+0+5=7)

    要得到最大美味值,一种可行的方案是,狐狸先喝水,然后按顺序吃饼 (2+7+7=16)

    $1≤N≤105,0≤T_i,W≤109 $。

    贪心。

    观察题目,我们不难发现,要得到最大美味值,狐狸应该先交错吃温度最大的和最小的饼干,其中如果能喝冰水或开水就更好了。所以我们给所有饼干按照温度排序,交替选择左右端点吃,如果先喝水再吃能获得更大美味值就更好啦。这样最大美味值就求出来啦。(注意左右端点谁先开始,可能得到两个答案,再取个 max。)

    那么最小美味值呢?我们肯定按照温度顺序吃饼干。这样每两个饼干之间的差值就是美味度。比如我们记第 (i) 个饼干和 (i-1) 个饼干的差值为 (T_i-T_{i-1}),则第 (i+1) 个饼干和 (i) 个饼干的差值为 (T_{i+1}-T_i),我们容易得到:如果不喝水,差值即为 (T_n-T_1)。此时即可分类讨论:

    (1) 如果水温度在 ([T_1,T_n]) 之间,喝水与不喝水,对答案没有影响,答案就是 (T_n-T_1)。(想一想,为什么?)

    (2) 如果水温度小于 (T_1),我们又必须要喝水,答案再加上 (W-T_1),即为 (T_n-W)

    (3) 同理如果水温大于 (T_n),答案即为 (W-T_1)

    合并以上算式我们可以得到 ( ext{MinAns}=max{W-T_1,0}+max{T_n-W,0}).

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    #define ll long long
     
    int n, w; ll d[100003], anl, anh1, anh2;
     
    int main() {
        scanf("%d%d", &n, &w);
        for (int i=1; i<=n; ++i) scanf("%lld", &d[i]);
        sort(d+1, d+n+1);
        anl=max(0ll, w-d[1])+max(0ll, d[n]-w);
        ll las=w, l=1ll, r=n;
        for (int i=1; i<=n; ++i) {
            if (i&1) anh1+=max(abs(d[l]-w), abs(d[l]-las)), las=d[l++];
            else anh1+=max(abs(d[r]-w), abs(d[r]-las)), las=d[r--];
        }
        las=w, l=1ll, r=n;
        for (int i=1; i<=n; ++i) {
            if (i&1) anh2+=max(abs(d[r]-w), abs(d[r]-las)), las=d[r--];
            else anh2+=max(abs(d[l]-w), abs(d[l]-las)), las=d[l++];
        }
        printf("%lld %lld
    ", anl, max(anh1, anh2));
        return 0;   
    }
    
  • 相关阅读:
    401. Binary Watch
    46. Permutations
    61. Rotate List
    142. Linked List Cycle II
    86. Partition List
    234. Palindrome Linked List
    19. Remove Nth Node From End of List
    141. Linked List Cycle
    524. Longest Word in Dictionary through Deleting
    android ListView详解
  • 原文地址:https://www.cnblogs.com/greyqz/p/9931552.html
Copyright © 2011-2022 走看看