• Gym101341题解


    难度分类

    (div2A-B):B C D G H M

    (div2C-D):E K

    (  div2E  ):A J I

    喵喵喵:F L

    A.

    B.

    题意:给一个长度为2~2e5的串,交换两个字符,要求最后没有"happiness" 

    坑点:本来没有"happiness",交换一把,出现了“happiness”,这下好!

    code1:(比赛时的,一点也不典雅~)

    #include <iostream>
    #include <vector>
    #include <cstring>
    using namespace std;
    char s[500000+10];
    vector<int> v;
    int main()
    {
        scanf("%s", s+1);
        int n = strlen(s+1);
        for(int i=1;i+8<=n;i++)
        {
            if(s[i] == 'h' && s[i+1] == 'a' && s[i+2] == 'p' && s[i+3] == 'p' && s[i+4] == 'i' && s[i+5] == 'n'&& s[i+6] == 'e' && s[i+7] == 's' && s[i+8] == 's') 
            {
                v.push_back(i);
            }
        }
    
        if(v.size() == 0)
        {
            printf("YES
    ");
            for(int i=2;i<=n;i++)
            {
                swap(s[1], s[i]);
                int gg = 0;
                if(i+8<=n && s[i] == 'h' && s[i+1] == 'a' && s[i+2] == 'p' && s[i+3] == 'p' && s[i+4] == 'i' && s[i+5] == 'n'&& s[i+6] == 'e' && s[i+7] == 's' && s[i+8] == 's') 
                {
                    gg = 1;
                }
                if(1+8<=n && s[1] == 'h' && s[2] == 'a' && s[3] == 'p' && s[4] == 'p' && s[5] == 'i' && s[6] == 'n'&& s[7] == 'e' && s[8] == 's' && s[9] == 's') 
                {
                    gg = 1;
                }
                if(gg == 0)
                {
                    printf("%d %d
    ", 1, i);
                    return 0;
                }
                swap(s[1], s[i]);
            }
        }
    
        if(v.size() == 1)
        {
            printf("YES
    ");
            printf("%d %d
    ", v[0], v[0]+1);
        }
    
        if(v.size() == 2)
        {
            printf("YES
    ");
            printf("%d %d
    ", v[0], v[1]+1);
        }
    
        if(v.size() > 2)
        {
            printf("NO
    ");
        }
    }

    code2: 待补。。。

    C.

    题意:给a个红球,b个绿球,c个不知道颜色的球,问,保证拿出的球中,红球

    不超过n,绿球不超过m,最多能拿几个球。 

    solve: 比赛时读错题了,懵逼了半天。

    如果a+c>n,那么拿n+1个球有可能GG.

    如果b+c>m,那么拿m+1个球有可能GG.

    code:

    #include <iostream>
    using namespace std;
    typedef long long LL;
    LL ans = 0;
    int main()
    {
        LL a, b, c, m, n;
        cin >> a >> b >> c >> n >> m;
        ans = a + b + c;
        if(a+c > n) ans = min(n, ans);
        if(b+c > m) ans = min(m, ans);
        cout << ans << endl;
    }

    D.

    题意:一只蛤,在一根线上跳,每次可以跳的距离给出了,问能否跳到目标。

    坑点:负数和0的特判

    #include <iostream>
    using namespace std;
    typedef long long LL;
    LL gcd(LL a, LL b)
    {
        return b==0?a:gcd(b, a%b);
    }
    int n;
    LL x, ans, k;
    int main()
    {
        cin >> n >> k;
        for(int i=1;i<=n;i++)
        {
            scanf("%I64d", &x);
            if(x<0) x = -x;
            if(i==1) ans = x;
            if(x==0) continue;
            ans = gcd(ans, x);
        }
        if(k % ans == 0) cout << "YES";
        else cout << "NO";
    }

    E.

    题意:数轴上有n个可以互相传送的点,和m个宝石。移动1个距离,-1s,传送门之间相互传送不消耗时间

    问吃完所有宝石最小耗费。

    solve:

    hint 1:离散化.

    hint 2:传送门i与传送门(i+1)之间的宝石,有2种处理方式。

    a) 从一个门直接移动到另一个门。时间耗费为| p[i+1]-p[i] |.

    b) 相邻宝石最大间距为maxlen,时间耗费为 2 * (| p[i+1]-p[i] |  -  maxlen).

    画个图,更好理解!

    #include <iostream>
    #include <algorithm>
    #include <map>
    #include <vector>
    using namespace std;
    typedef long long LL;
    const int NICO = 200000 + 10;
    int n, m;
    LL t[NICO], b[NICO];
    vector<LL> v; 
    map<LL, int> mp;
    int main()
    {
        scanf("%d %d", &n, &m);
        for(int i=1;i<=n;i++)
        {
            scanf("%I64d", &t[i]);
            v.push_back(t[i]);
        }
        t[0] = -1e16, t[n+1] = 1e16;
        int pos = 1;
        for(int i=1;i<=m;i++)
        {
            scanf("%I64d", &b[i]);
            v.push_back(b[i]);
        }
        sort(v.begin(), v.end());
    
        for(int i=0;i<v.size();i++)
        {
            mp[v[i]] = i;
        }
        LL ans = 2L * (v[v.size() - 1] - v[0]);
        for(int i=1;i<n;i++)
        {   
            int l = mp[t[i]], r = mp[t[i+1]];
            LL mx = 0;
            for(int j=l;j<r;j++)
            {
                mx = max(mx, v[j+1] - v[j]);
            }
            mx = mx*2L;
            mx = max(mx, t[i+1] - t[i]);
            ans -= mx;
        }   
        cout << ans << endl;
    }   

    F.

    G.

    题意:gay里gay气的CF...... 一群人,如果A对B产生了爱慕之情,A就将自己的name改成I_love_B.

    按时间顺序给出了一些爱慕的关系,问1号,最终的name是什么。

    题解:逆向来一遍就行了。

    #include <iostream>
    using namespace std;
    const int NICO = 200000 + 10; 
    int n, m, u, v;
    char s[NICO][40];
    int a[NICO], b[NICO];
    int main()
    {
        scanf("%d", &n);
        for(int i=1;i<=n;i++)
        {
            scanf("%s", s[i]);
        }
        scanf("%d", &m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d %d", &a[i], &b[i]);
        }
        int need = 1;
        for(int i=m;i>=1;i--)
        {
            if(a[i] == need)
            {
                printf("I_love_");
                need = b[i];
            }
        }
        printf("%s
    ", s[need]);
    
    }

    H.

    题意:一个矩阵,拿掉一个十字架(莫名想到硫磺火),让剩下的数字中最大值最小,求最小值~

    题解:预处理,求出每个元素左上,左下,右上,右下最小值。

    #include <iostream>
    using namespace std;
    const int NICO = 1002;
    int n, m;
    int a[NICO][NICO], l[NICO][NICO], r[NICO][NICO];
    int lu[NICO][NICO], ld[NICO][NICO], ru[NICO][NICO], rd[NICO][NICO];
    int main()
    {
        scanf("%d %d", &n, &m);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                scanf("%d", &a[i][j]);
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++) 
            {
                l[i][j] = max(l[i][j-1], a[i][j]);
            }
            for(int j=m;j>=1;j--)
            {
                r[i][j] = max(r[i][j+1], a[i][j]);
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                lu[i][j] = max(l[i][j], lu[i-1][j]);
                ru[i][j] = max(r[i][j], ru[i-1][j]);
            }
        }
        for(int i=n;i>=1;i--)
        {
            for(int j=1;j<=m;j++)
            {
                ld[i][j] = max(l[i][j], ld[i+1][j]);
                rd[i][j] = max(r[i][j], rd[i+1][j]);
            }
        }
        int ans = 1e9+7, cx = -1, cy = -1;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                int t1 = max(lu[i-1][j-1], ru[i-1][j+1]);
                int t2 = max(ld[i+1][j-1], rd[i+1][j+1]);
                int t3 = max(t1, t2);
                if(t3 < ans)
                {
                    cx = i, cy = j;
                    ans = t3;
                }
            }
        }
        printf("%d %d
    ", cx, cy);
    }

    I.

    J.  (炒鸡好玩的一道题)

    题意:给一颗树,两个人准备制定好路线,准备抓一个怪物,这个怪物跑得很快。

    并且知道了两人路线。问有没有可能抓到怪物。

    题解:

    hint 1: A守住重要隘口,B遍寻涯角~ 这就是我们大致的思路。

     

    图画的好恐怖。。。。。。。。。。。。。。。

    A守住1,然后B把两个圈圈里面的点扫一遍即可。

    hint 2: 然后我们发现,A要守的节点必须是链状的。B要访问的每一个分支,也

    得是链状的。

    有趣的结论:从叶子节点向上删点,删到出现岔路为止。然后判断接下来的剩下的

    图是不是一根链即可。

    code:

     1 #include <iostream>
     2 #include <vector>
     3 #include <set>
     4 using namespace std;
     5 const int NICO = 200000 + 10;
     6 int n, u, v, deg[NICO], flag[NICO];
     7 vector<int> vec[NICO];
     8 void dfs(int x, int p)
     9 {
    10     flag[x] = 1;
    11     for(int i=0;i<vec[x].size();i++)
    12     {
    13         if(vec[x][i] == p) continue;
    14         if(deg[vec[x][i]] <= 2)
    15         {
    16             dfs(vec[x][i], x);
    17         }
    18     }
    19 }
    20 int main()
    21 {
    22     scanf("%d", &n);
    23     for(int i=1;i<n;i++)
    24     {
    25         scanf("%d %d", &u, &v);
    26         vec[u].push_back(v);
    27         vec[v].push_back(u);
    28         deg[u] ++, deg[v] ++;
    29     }
    30     for(int i=1;i<=n;i++)
    31     {
    32         if(deg[i] > 1) continue;
    33         int t = i; dfs(t, -1);
    34     }
    35 
    36     for(int i=1;i<=n;i++)
    37     {
    38         if(flag[i]) continue;
    39         int cnt = 0;
    40         for(int j=0;j<vec[i].size();j++)
    41         {
    42             if(flag[vec[i][j]]) continue;
    43             cnt ++;
    44         }
    45         if(cnt >= 3)
    46         {
    47             printf("NO
    ");
    48             return 0;
    49         }
    50     }
    51     printf("YES
    ");
    52 
    53 }

    K.

    L.

    M.

    贪心!每次选GG的人从最后面拿,为前面腾出空间即可。

    #include <iostream>
    #include <vector>
    using namespace std;
    const int NICO = 200000 + 10;
    typedef long long LL;
    LL sum = 0;
    int a[NICO], n;
    vector<int> v1, v2;
    int main()
    {
        scanf("%d", &n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d", &a[i]);
            sum += a[i];
        }
        if(sum > n)
        {
            printf("NO
    ");
            return 0;
        }
        int ok = 1;
        int pos = n;
        for(int i=n;i>=1;i--)
        {
            if(a[i] > 0)
            {
                for(int j=pos;j>=pos-a[i]+1;j--)
                {
                    if(i >= j) ok = 0;
                    v1.push_back(i);
                    v2.push_back(j);
                }
            }
            pos = pos-a[i];
        }
        if(ok == 0)
        {
            printf("NO
    ");
            return 0;
        }
        printf("YES
    ");
        for(int i=0;i<v1.size();i++)
        {
            printf("%d %d
    ", v1[i], v2[i]);
        }
    }
  • 相关阅读:
    java后台生成图片二维码
    layui框架下的摸索与学习
    eclipse/myeclipse中js/java的自动提示只有4个字符怎么解决
    Git日常操作指令
    node指南开发练习笔记(1)-- express
    echart全国主要城市某数据的显示
    微信公众号开发获取当前位置
    显示上传图片
    移动端Safari onclick事件兼容
    Plupload上传插件自定义图片的修改
  • 原文地址:https://www.cnblogs.com/RUSH-D-CAT/p/6707980.html
Copyright © 2020-2023  润新知