• CF #578 Div2


    // 比赛链接:https://codeforces.com/contest/1200

    A - Hotelier

    题意:

    有一家旅馆有10间房,编号0~9,从左到右顺序排列。旅馆有左右两扇门,每次新来旅客从进来门的方向分配最近的空闲房间。给你一段旅客到来方向以及离开位置的序列,输出最终旅馆房间使用情况。

    输入:

    8

    LLRL1RL1

    输出:

    1010000011

    题解:

    序列长度不超过10^5,暴力模拟复杂度O(10*n)。

    AC代码:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    char s[100010];
    bool r[10];  // true:有人  false:无人
    int main()
    {
        int n; cin>>n;
        scanf("%s", s);
        for(int i=0;i<n;i++) {
            if(s[i]=='L') {
                for(int j=0;j<=9;j++) {
                    if(!r[j]) {
                        r[j] = 1;
                        break;
                    }
                }
            } else if(s[i]=='R') {
                for(int j=9;j>=0;j--) {
                    if(!r[j]) {
                        r[j] = 1;
                        break;
                    }
                }
            } else {
                r[s[i]-'0'] = 0;
            }
        }
        for(int i=0;i<=9;i++) {
            putchar(r[i]?'1':'0');
        }
    
        return 0;
    }
    View Code

    B - Block Adventure

    题意:

    从起点到终点有 n 个格子,每块高度 h[i],初始时背包有m块方块,从 i 跳到 i+1 有三种选择,1. 把背包的方块放到当前的格子上;2. 把当前格子的方块放到背包里;3.跳到下一块。

    只有当 | h[i] - h[i+1] | <= k 才能跳到下一块。 问是否能跳到终点。

    输入:

    第一行组数,后面每组第一行 n,m,k,第二行 n个值代表 h[i]。


    3 0 1
    4 3 5
    3 1 2
    1 4 7
    4 10 0
    10 20 10 20
    2 5 5
    0 11
    1 9 9
    99

    输出:

    YES
    NO
    YES
    NO
    YES

    题解:

    贪心

    如果能跳到下一块,(左边能凑到的最多方块要大于等于右边最少需要的方块,即m+h[i]>= h[i+1]-k ),把前一块上的方块取到前后差值不超过 k。否则跳不到终点。

    AC代码:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    int h[110];
    int main()
    {
        int t; cin>>t;
        while(t--) {
            int n, m, k;
            scanf("%d %d %d", &n, &m, &k);
            for(int i=0;i<n;i++) {
                scanf("%d", &h[i]);
            }
            bool flag = true;
            for(int i=0;i+1<n;i++) {
                if(h[i]+m>=h[i+1]-k) {
                    if(h[i+1]>=k) m = h[i]+m - (h[i+1]-k);
                    else 
                        m = h[i]+m;
                }
                 else {
                    flag = false;
                    break;
                }
            }
        
            if(flag) printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }
    View Code

    C - Round Corridor

    题意:

    一个圆盘,内层分割成m块,外层分割成n块,给出 q 个询问,判断所给两块区域是否连通。

    输入:

    第一行 n,m,q,后面 q 行,每行四个数 sx,sy,ex,ey。sx,ex 为 1 代表内层,为 2 代表外层;sy,ey 代表编号,如图顺时针排序。

    4 6 3
    1 1 2 3
    2 6 1 2
    2 6 2 4

    输出:

    YES
    NO
    YES

    题解:

    思维题。设 g = gcd(m, n),由图可知 1*g,2*g,3*g,…… k*g 把圆盘分割开。这些单独块之内连通,不在同一块则不连通。

     AC代码:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    typedef long long ll;
    ll gcd(ll a, ll b) {
        return b==0?a:gcd(b, a%b);
    }
    
    ll g, m, n;
    ll f(int d, ll v) { // 计算 v 所在块的编号
        if(d==1) return v/(m/g);
        else return v/(n/g);
    }
    int main() {
        int q;
        cin>>m>>n>>q;
        int sx, ex;
        ll sy, ey;
        g = gcd(m, n);
        while(q--) {
            scanf("%d %lld %d %lld", &sx, &sy, &ex, &ey);
            if(f(sx, sy-1)==f(ex, ey-1)) printf("YES
    ");
            else printf("NO
    ");
    
        }
    
        return 0;
    }
    View Code

    E - Compress 

    题意:

     有1e5个单词,当前一个单词的后缀与后一个单词的前缀相同时,相同部分可以压缩省略,这个过程递归进行。输出一行字符串表示最终结果。

    输入:

    5

    I want to order pizza

    输出:

    Iwantorderpizza

    题解:

     字符串哈希

    AC代码:

     注意压缩过程是递归进行的,没注意一直WA5。

    单模数哈希WA78,可能没取好模数吧。双模数哈希AC。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    typedef long long ll;
    
    const int N = 1e6 + 10;
    const int Base1 = 1009;
    const int Base2 = 233;
    const int Mod1 = 1e9 + 7;
    const int Mod2 = 998244353;
    char s[N], ans[N];
    
    int main() {
        int n;
        scanf("%d", &n);
        int len = 0;     // 前一个串长度
        for(int i = 0; i < n; ++i) {
            scanf("%s", s);
            int m = strlen(s);
    
            ll now1 = 0, last1 = 0;   // 前面所有串的哈希,当前串的哈希
            ll now2 = 0, last2 = 0;
            ll bs1 = 1, bs2 = 1;
            int same = 0;  // 公共长度
            for(int k = 1; k <= m && k <= len; ++k) {
                now1 = (now1*Base1 + s[k-1]) % Mod1;       // 从前往后加
                last1 = (bs1*ans[len-k] + last1) % Mod1;   // 从后往前加
                bs1 = bs1 * Base1 % Mod1;
    
                now2 = (now2*Base2 + s[k-1]) % Mod2;      
                last2 = (bs2*ans[len-k] + last2) % Mod2;  
                bs2 = bs2 * Base2 % Mod2;
    
                if(now1==last1 && now2==last2) same = k;
            }
            for(int k = same; k < m; ++k) {
                ans[len++] = s[k];
            }
        }
          ans[len] = '';
          puts(ans);
          return 0;
    }
    View Code
  • 相关阅读:
    python框架---->APScheduler的使用
    python基础---->python的使用(六)
    python爬虫---->scrapy的使用(一)
    python基础---->python的使用(四)
    python基础---->python的使用(一)
    网页mp3播放代码
    js打开没有地址栏下拉条新窗口
    php全面获取url地址栏及各种参数
    php分页类
    php生成随机密码的几种方法
  • 原文地址:https://www.cnblogs.com/izcat/p/11338978.html
Copyright © 2020-2023  润新知