传送门
A. Diverse Strings
解题思路:先对字符串排序然后判断一下就行了。
#include<bits/stdc++.h>
#define il inline
#define pb push_back
#define fi first
#define se second
#define ms(_data,v) memset(_data,v,sizeof(_data))
#define sc(n) scanf("%d",&n)
#define SC(n,m) scanf("%d%d",&n,&m)
#define sz(a) int((a).size())
#define rep(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
bool pd(string s) {
sort(s.begin(),s.end());
for (int i=1;i<sz(s);++i) if (s[i]!=s[i-1]+1) return false;
return true;
}
int n;
int main(){
cin>>n;
rep(i,1,n) {
string s;
cin>>s;
cout<<(pd(s)? "Yes\n" : "No\n");
}
}
B. Parity Alternated Deletions
解题思路:如果奇数个数和偶数个数相差不超过1,那就是可以取完的,反之我们去不掉的,那就剩下小的就好了。
#include<bits/stdc++.h>
#define il inline
#define pb push_back
#define fi first
#define se second
#define ms(_data,v) memset(_data,v,sizeof(_data))
#define sc(n) scanf("%d",&n)
#define SC(n,m) scanf("%d%d",&n,&m)
#define sz(a) int((a).size())
#define rep(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
vector<int> even,odd;
int n,tp;
int main() {
std::ios::sync_with_stdio(0);
cin>>n;
rep(i,1,n) {
cin>>tp;
if(tp&1) odd.pb(tp);
else even.pb(tp);
}
if(abs(sz(odd)-sz(even))<=1) cout<<0<<endl;
else {
ll sum=0;
sort(odd.begin(),odd.end());
sort(even.begin(),even.end());
if(sz(odd)>sz(even)) rep(i,0,sz(odd)-sz(even)-2) sum+=odd[i];
else rep(i,0,sz(even)-sz(odd)-2) sum+=even[i];
cout<<sum<<endl;
}
return 0;
}
C. Two Shuffled Sequences
解题思路:一个元素个数超过3个那肯定不能分成两个满足条件的序列,如果两个一样的元素那就每个序列放一个,反之放哪个都是一样的,最后排个序就行了。
#include<bits/stdc++.h>
#define il inline
#define pb push_back
#define fi first
#define se second
#define ms(_data,v) memset(_data,v,sizeof(_data))
#define sc(n) scanf("%d",&n)
#define SC(n,m) scanf("%d%d",&n,&m)
#define sz(a) int((a).size())
#define rep(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const int maxn=2e5+5;
int n,tp;
bool f1,f2;
map<int,int> num;
vector<int> de,inde;
int main(){
std::ios::sync_with_stdio(0);
cin>>n;
rep(i,1,n){
cin>>tp;
if(++num[tp]>=3) f1=1;
if(num[tp]==2) f2=1;
}
if(f1) cout<<"NO"<<endl;
else if(!f2){
cout<<"YES"<<endl<<num.size()<<endl;
for(auto it=num.begin();it!=num.end();++it) cout<<it->fi<<" ";
cout<<endl<<0<<endl;
}
else{
for(auto it=num.begin();it!=num.end();++it){
if(it->se==2) de.pb(it->fi),inde.pb(it->fi);
else de.pb(it->fi);
}
sort(de.begin(),de.end());
sort(inde.begin(),inde.end(),greater<int>() );
cout<<"YES"<<endl<<de.size()<<endl;
rep(i,0,sz(de)-1) cout<<de[i]<<" ";
cout<<endl<<inde.size()<<endl;
rep(i,0,sz(inde)-1) cout<<inde[i]<<" ";
}
return 0;
}
D. Equalize Them All
解题思路:让所有的数字变成那个出现频率最高的数无疑是步数最少的,题干中的那步操作,其实就是使两个数字相同,大了那就减去差,小了那就加上差,所有只要从出现频率最高的那个数字开始往两边走就行了,大了就2操作,小了就1操作。(不需要像代码还找个区间,写烦了)
#include<bits/stdc++.h>
#define il inline
#define pb push_back
#define fi first
#define se second
#define ms(_data,v) memset(_data,v,sizeof(_data))
#define sc(n) scanf("%d",&n)
#define SC(n,m) scanf("%d %d",&n,&m)
#define sz(a) int((a).size())
#define rep(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const int maxn=2e5+5;
int n,a[maxn],le=1,ri=1,num,id;
int co[maxn];
struct node{
int x,i,j;
}ans[maxn];
int main(){
std::ios::sync_with_stdio(0);
cin>>n;
rep(i,1,n){
cin>>a[i];
co[a[i]]++;
if(co[a[i]]>num){
num=co[a[i]];
id=a[i];
}
}
for(int i=1;i<=n;++i){
if(a[i]==id){
int j;
for(j=i;j<=n;++j) if(a[j]!=id) break;
le=i,ri=j-1;
break;
}
}
int cnt=0;
for(int i=le-1;i>=1;--i){
if(a[i]>id) ans[++cnt]=node{2,i,i+1};
else if(a[i]<id) ans[++cnt]=node{1,i,i+1};
}
for(int i=ri+1;i<=n;++i){
if(a[i]>id) ans[++cnt]=node{2,i,i-1};
else if(a[i]<id) ans[++cnt]=node{1,i,i-1};
}
cout<<cnt<<endl;
rep(i,1,cnt) cout<<ans[i].x<<" "<<ans[i].i<<" "<<ans[i].j<<endl;
return 0;
}
E. Median String
解题思路:如果给我们两个数求他们中间的那个数,我们都会求,加起来除2就行了,我们可以把字符串看成26进制不就行了嘛。模拟26进制计算,最后在转化回字符串就行了。
#include<bits/stdc++.h>
#define il inline
#define pb push_back
#define fi first
#define se second
#define ms(_data,v) memset(_data,v,sizeof(_data))
#define sc(n) scanf("%d",&n)
#define SC(n,m) scanf("%d %d",&n,&m)
#define sz(a) int((a).size())
#define rep(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const int maxn=2e5+7;
int n,sum[maxn];
string a,b;
map<int,int> mp;
int main(){
std::ios::sync_with_stdio(0);
cin>>n>>a>>b;
int i=0;
for(char x='a';x<='z';++x){
mp[x]=i,mp[i]=x,++i;
}
int cur=0,tp,cnt=0;
for(int i=sz(a)-1;i>=0;--i){
tp=mp[a[i]]+mp[b[i]]+cur;
sum[cnt]=tp%26;
cur=tp/26;
cnt++;
}
if(cur) sum[cnt]=cur;
else cnt--;
for(int i=cnt;i>=0;--i){
if(sum[i]&1) sum[i-1]+=26;
sum[i]/=2;
}
if(cnt>n-1) cnt--;
for(int i=cnt;i>=0;--i) cout<<char(mp[sum[i]]);
return 0;
}
F. Graph Without Long Directed Paths
解题思路:分析题意,不能有>=2的路径,其实就是每个点的边,要不就是全部指向它,要不然就是全部从它出去。这样就不会有>=2的路径出现了。然后我们用搜索就可以解决这个问题,我写的比较啰嗦.....丧。
#include<bits/stdc++.h>
#define il inline
#define pb push_back
#define fi first
#define se second
#define ms(_data,v) memset(_data,v,sizeof(_data))
#define sc(n) scanf("%d",&n)
#define SC(n,m) scanf("%d %d",&n,&m)
#define sz(a) int((a).size())
#define rep(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const int maxn=2e5+7;
bool ans[maxn],vis[maxn];
struct edge{
int id,x,y;
bool fg;
};
vector<edge> mp[maxn];
bool pd=0;
int n,m;
void solve(int np,bool fg){ //当前点,fg=0代表所有的边都是出边,反之入边
rep(i,0,sz(mp[np])-1){
edge tp=mp[np][i];
if(pd) return;
if(!vis[tp.id]){
vis[tp.id]=1;
if(tp.x==np && fg==1) ans[tp.id]=0;
else if(tp.x==np && fg==0) ans[tp.id]=1;
else if(tp.x!=np && fg==1) ans[tp.id]=1;
else if(tp.x!=np && fg==0) ans[tp.id]=0;
if(tp.x!=np) solve(tp.x,fg^1);
else solve(tp.y,fg^1);
}
else{
if(fg==1 && tp.x==np && ans[tp.id]==1){
pd=1;return;
}
else if(fg==1 && tp.x!=np && ans[tp.id]==0){
pd=1;return;
}
else if(fg==0 && tp.x==np && ans[tp.id]==0){
pd=1;return;
}
else if(fg==0 && tp.x!=np && ans[tp.id]==1){
pd=1;return;
}
}
}
}
int main(){
std::ios::sync_with_stdio(0);
cin>>n>>m;
int x,y;
rep(i,1,m){
cin>>x>>y;
mp[x].pb(edge{i,x,y,0});
mp[y].pb(edge{i,x,y,0});
}
solve(1,0);
if(pd) cout<<"NO"<<endl;
else{
cout<<"YES"<<endl;
rep(i,1,m) cout<<ans[i];
}
return 0;
}
G. Two Merged Sequences
解题思路:对于一个数如果它只能放两个队列之一,那我就将其放入,如果两个都不能,那这个数列构造肯定就失败了。
如果它两个队列都能放入呢,那我们就看它的下一个元素,会有三种情况,1.相同,那就每个队列塞一个。2.下一个元素比它大,那就把他放到递增序列。3.下一个元素比它小,那就把它放到递减序列。这样考虑其实对当前元素不作选择了,因为我们这样放,它不影响下一个元素选择摆放。
#include<bits/stdc++.h>
#define il inline
#define pb push_back
#define fi first
#define se second
#define ms(_data,v) memset(_data,v,sizeof(_data))
#define sc(n) scanf("%d",&n)
#define SC(n,m) scanf("%d %d",&n,&m)
#define sz(a) int((a).size())
#define rep(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const int maxn=2e5+5;
int n,a[maxn];
bool ans[maxn];
priority_queue<int,vector<int>,greater<int> > inde; //下降
priority_queue<int> de; //上升序列
int main() {
std::ios::sync_with_stdio(0);
cin>>n;
rep(i,1,n) cin>>a[i];
if(n==1){
cout<<"YES"<<endl<<1<<endl;
return 0;
}
de.push(-inf),inde.push(inf);
int i=1;
if(a[i+1]>a[i]) de.push(a[i]),ans[i]=0;
else if(a[i+1]<a[i]) inde.push(a[i]),ans[i]=1;
else de.push(a[i]),inde.push(a[++i]),ans[i-1]=0,ans[i]=1;
++i;
while(i<=n) {
if(a[i]>de.top() && a[i]<inde.top()) {
if(a[i+1]>a[i]) de.push(a[i]),ans[i]=0;
else if(a[i+1]<a[i]) inde.push(a[i]),ans[i]=1;
else de.push(a[i]),inde.push(a[++i]),ans[i-1]=0,ans[i]=1;
}
else if(a[i]>de.top()) de.push(a[i]),ans[i]=0;
else if(a[i]<inde.top()) inde.push(a[i]),ans[i]=1;
else {
cout<<"NO"<<endl;
return 0;
}
++i;
}
cout<<"YES"<<endl;
rep(i,1,n) cout<<ans[i]<<" ";
return 0;
}