A
题意
给你一个字符串,你可以将其分为任意多段,需要保证任意一段\((i,j)\),都有\(i_{th}\)段的首字母小于\(j_{th}\)段的尾字母,判断能否执行。
方法
直接分成两段即可。
代码
#include<bits/stdc++.h> using namespace std; using ll=long long; void solve() { int n; cin>>n; string s; cin>>s; if(s[0]!=s[n-1]) cout<<"YEs\n"; else cout<<"NO\n"; } int main() { int t=1; cin>>t; while(t--) solve(); return 0; }
|
B
题意
存在一个数列,Alice和Bob轮流进行操作,Alice可以选择\((a_i,a_{i+1})\),然后选择将\(a_i\)变为两者中比较大的,\(a_{i+1}\)删去。Bob也可以进行操作,进行类似的操作(这里是取较小的)。Alice的目的是\(a_1\)尽可能大,Bob相反,求最后的结果。
方法
不难想到:Alice每次取最小的删去,Bob取最大的删去,这样轮流操作,可以得到最后的答案就是中位数。(先排序)
代码
#include<bits/stdc++.h> using namespace std; using ll=long long; void solve() { int n; cin>>n; std::vector<int> a(n,0); for (int i = 0; i < n; ++i) { cin>>a[i]; } sort(a.begin(),a.end(),greater<int>()); cout<<a[(n+1)/2-1]<<"\n"; } int main() { int t=1; cin>>t; while(t--) solve(); return 0; }
|
C
题意
给你一个字符串,要求你进行重排,使得”好对“最多,(好对:快乐对或者是一个子段首尾相同)。
快乐对:一个子段内部存在两个相邻的字符\(a_k,a_{k+1}\),(\(a_k,a_{k+1}\)不同)使得\(a_k\)不等于子段首字母,或者\(a_{k+1}\)不等于子段尾字母不同时成立。
方法
可以想到:最短的快乐对就是两个字符,并且互不相同。这样就可以尽可能的多。另外不难发现:好对的数目是确定的(即两个字符相同)。如果两个字符相邻,那么快乐对的数目也会减少。所以我们可以这样进行构造:
循环出现,出现次数多的尽可能先出现,知道全部消失为止。
代码
#include<bits/stdc++.h> using namespace std; using ll=long long; void solve() { int n; cin>>n; string s; cin>>s; std::map<int,int> map; for (int i = 0; i < n; ++i) { map[s[i]-'a']++; } std::vector<pair<int,int>> v; for(int i=0;i<26;i++) { if(map[i]!=0) { v.push_back({map[i],i}); } } sort(v.begin(),v.end(),greater<pair<int,int>>()); while(1) { bool ok=false; for(auto &[x,y]: v) { if(x!=0) { ok=true; cout<<char(y+'a'); x--; } } if(ok==false) { break; } } cout<<"\n"; } int main() { int t=1; cin>>t; while(t--) solve(); return 0; }
|