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\n");
        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\n", 1, i);
                return 0;
            }
            swap(s[1], s[i]);
        }
    }

    if(v.size() == 1)
    {
        printf("YES\n");
        printf("%d %d\n", v[0], v[0]+1);
    }

    if(v.size() == 2)
    {
        printf("YES\n");
        printf("%d %d\n", v[0], v[1]+1);
    }

    if(v.size() > 2)
    {
        printf("NO\n");
    }
}

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\n", 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\n", 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\n");
48             return 0;
49         }
50     }
51     printf("YES\n");
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\n");
        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\n");
        return 0;
    }
    printf("YES\n");
    for(int i=0;i<v1.size();i++)
    {
        printf("%d %d\n", v1[i], v2[i]);
    }
}
时间: 2024-08-27 01:38:43

Gym101341题解的相关文章

洛谷 P1079 Vigen&#232;re 密码 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problem/show?pid=1079 题目描述 16 世纪法国外交家 Blaise de Vigenère 设计了一种多表密码加密算法――Vigenère 密 码.Vigenère 密码的加密解密算法简单易用,且破译难度比较高,曾在美国南北战争中为 南军所广泛使用. 在密码学中,我们称需要加密的信息为明文,用 M 表示:称加密后的信息为密文,用 C 表示:而密钥是一种

8.8联考题解

今天的T1让我怀疑我是不是在做奥赛题--这考的是什么知识点啊这个,会不会用绝对值函数? Evensgn 的债务 时间限制: 1 Sec  内存限制: 128 MB 题目描述 Evensgn 有一群好朋友,他们经常互相借钱.假如说有三个好朋友A,B,C.A 欠 B 20 元,B 欠 C 20 元,总债务规模为 20+20=40 元.Evensgn 是个追求简约的人,他觉得这样的债务太繁杂了.他认为,上面的债务可以完全等价为 A 欠C20 元,B 既不欠别人,别人也不欠他.这样总债务规模就压缩到了 

POJ 2533 - Longest Ordered Subsequence(最长上升子序列) 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:http://poj.org/problem?id=2533 Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given numeric sequence (a1, a2, ..., aN) be any sequence (ai1, ai2, ..., aiK)

(leetcode题解)Pascal&#39;s Triangle

Pascal's Triangle  Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5,Return [ [1], [1,1], [1,2,1], [1,3,3,1], [1,4,6,4,1] ] 题意实现一个杨辉三角. 这道题只要注意了边界条件应该很好实现出来,C++实现如下 vector<vector<int>> generate(int

2017ZZUACM省赛选拔试题部分题解----谨以纪念我这卡线滚粗的美好经历

写在前面: 其实心里有些小小的不爽又有点小小的舒畅,为啥捏?不爽当然是因为没被选拔上啦,舒畅捏则是因为没被选拔上反而让自己警醒,学长也提点很多很多."沉下去,然后一战成名"学长如是对我说,我很开心.其实这完全算不算是题解,只是我个人的一些小想法而已.而且到现在还有一题不会...让自己长点记性吧. 题目 A :聪明的田鼠 Time Limit: 1 Sec Memory Limit: 128 MB Description 田鼠MIUMIU来到了一片农田,农田可以看成是一个M*N个方格的矩

LeetCode-001题解

此题目摘自LeetCode001 Given an array of integers, find two numbers such that they add up to a specific target number. The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2.

leetcode题解: Next Permutation

最近还一直在刷leetcode,当然,更多时候只是将题解写在自己的电脑上,没有分享出来.偶尔想起来的时候,就写出来. public class Solution { public void nextPermutation(int[] nums) { if(nums==null||nums.length<=1) return; nextPermutationHelp( nums,0,nums.length-1); } public void nextPermutationHelp(int []nu

HDU 5014 Number Sequence(2014 ACM/ICPC Asia Regional Xi&#39;an Online) 题解

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5014 Number Sequence Problem Description There is a special number sequence which has n+1 integers. For each number in sequence, we have two rules: ● ai ∈ [0,n] ● ai ≠ aj( i ≠ j ) For sequence a and sequ

HDU 1045 Fire Net 二分图Bipartite题解

本题可以使用DFS直接爆搜出答案,不过这样类型的题目其实是个二分图的题解. 这个二分图,难不在Hungary算法,而是难在于建图.需要挺高的抽象思维的. 建图: 1 把同一行不被X分开的格子标同一个号码,被X分开的标下一个号码,这样做是为了缩点,不需要把所有的格子都分开标号,而且可以更方便建个更加小的图. 2 同理把同一列的格子标号 3 然后判断相同一个格子的行标号和列标号是有路径的,其他不在同一个格子的都是没有路径的. 4 这样就等于以行标号和列标号作为左右顶点,构建成一个二分图了 然后使用H