Codeforces Round #616 (Div. 1)

Mind Control

题目链接:https://codeforces.com/contest/1290/problem/A

题意:

  一共有n件物品,每件物品都有自己的价值。

  现有n个人,每个人可以按顺序随机从头或尾拿走一份礼物

  其中你排在第m位,并且你可以控制X个人指定他们拿头或尾的礼物

  问你最少能拿到多大的价值的物品

分析:

  我们令K = min(X , M-1),这是因为你能拿到礼物的价值只会受到前M-1个人影响

  此时你前面的K个人可以受你控制,M - 1 - K个人不会受到你的控制,我们令 M - 1 - K = C

  我们令 0 <= i <= K , 0 <= j <= C, i 表示你可以控制的且你让他从头拿走礼物的人

  j表示你不能控制的且他从头拿走礼物的人数,那么从尾拿走礼物的人数为(K - i) + (C - j)

  那么到你拿礼物的回合时头剩下的礼物就为 a[i + j + 1] , 尾剩下的礼物就为 a[n - (K - i) - (C-j)]

  因为题目给的数据范围比较小,所以我们就可以 N^2 暴力枚举啦

  枚举时我们要注意因为 j 的人数是不能控制的,所以我们要取枚举的所有 j 中的最小值

  而 i 的人数是我们可以控制的,所以我们要取枚举的所有 i 中的最大值

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 2e5 + 10;
ll a[N] , ans;
int main()
{
    int t , n , m , k , c , x;
    cin >> t;
    while(t --)
    {
        cin >> n >> m >> x ;
        for(int i = 1 ; i <= n ; i ++)    cin >> a[i];
        k = min(x , m - 1) , c = m - 1 - k , ans = 0 ;
        for(int i = 0 ; i <= k ; i ++)
        {
            ll now = (0x3f3f3f3f3f3fll);
            for(int j = 0 ; j <= c ; j ++)
                now = min(now , max(a[i + j + 1] , a[n - (k - i) - (c - j)]));
            ans = max(ans , now);
        }
        cout << ans << '\n';
    }
    return 0;
}

 

Irreducible Anagrams

题目链接:https://codeforces.com/contest/1290/problem/B

题意: 

  定义anagram,表示两个字符串的字符组成相同。

  定义reducible anagram,表示可以两个字符串可以拆分成k个子串,且每个子串都是anagram的。

  irreducible anagram 就是不满足条件的。

  现在给你一个字符串,然后q次询问,每次询问给你l,r。问你[l,r]的这个字符串,能否找到一个irreducible anagram。

分析:

  难点在题目难度

  不难发现当以下情况满足irreducible anagram

  ①、字符串长度为1

  ②、字符串首位不相同

  ③、字符串存在三个及以上不同字符

  操作①②直接O1判断,操作③预处理时统计每个字符的前缀个数,每次查询在遍历一遍即可

 

#include<bits/stdc++.h>
#define rep(i,a,n) for (int i=a;i<=n;i++)
using namespace std;
const int N = 3e5 + 10;
int cnt[N][37] , n , l , r;
string s;
int main()
{
    cin >> s;
    rep(i , 1 , s.size())
    {
        rep(j , 0 , 25)
        cnt[i][j] = cnt[i - 1][j];
        cnt[i][s[i - 1] - 'a'] ++ ;
    }
    cin >> n;
    while(n --)
    {
        cin >> l >> r;
        if(l == r) {cout << "Yes" << '\n' ; continue ;}
        if(s[l - 1] != s[r - 1]){cout << "Yes" << '\n' ; continue ;}
        int tot = 0;
        rep(j , 0 , 25)
        if(cnt[r][j] - cnt[l - 1][j])
        tot ++;
        if(tot >= 3) cout << "Yes" << '\n';
        else          cout << "No" << '\n';
    }
    return 0;
}

 

总结:第一次打div1,垫底了 T^T , 还好分掉的不多

posted @ 2020-02-09 03:25  GsjzTle  阅读(238)  评论(0编辑  收藏  举报