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 , 还好分掉的不多