A
void solve(){int n;cin>>n;int l,r;cin>>l>>r;string s;cin>>s;s=" "+s;for(int i=l;i<=r;i++){if(s[i]=='x'){cout<<"No"<<endl;return;}}cout<<"Yes"<<endl;
}
B
题意:给定一个由#
,.
,o
组成的字符串,修改字符串的.
,使得o
尽量多,且满足每个o
之间隔着一个#
void solve(){string s;cin>>s;int n=s.size();s=" "+s;vector<char>t(n+1);vector<int>vis(n+1);rep(i,1,n){if(s[i]=='#'){t[i]='#';vis[i]=1;}}//1 0//2 3int last=0;rep(i,1,n){if(s[i]=='#'){int ok=0;for(int j=last+1;j<=i-1;j++){if(s[j]=='o')ok=1;}if(ok)break;else{for(int j=last+1;j<=i-1;j++){if(s[j]=='.'){s[j]='o';break;}}}last=i;}}int ok=0;for(int j=last+1;j<=n;j++){if(s[j]=='o')ok=1;}if(!ok){for(int j=last+1;j<=n;j++){if(s[j]=='.'){s[j]='o';break;}}}rep(i,1,n){cout<<s[i];}
}
C
题意:给定n个字符串,把其中的k个拼接在一起,求字典序第x小的字符串
思路:
n^k<1e5,dfs+排序即可
int n,k,x;
vector<string>v;
void dfs(string s,vector<string>&a,int cal){if(cal==k){v.pb(s);return;}for(int i=1;i<=n;i++){dfs(s+a[i],a,cal+1);}
}
void solve(){cin>>n>>k>>x;vector<string>a(n+1);rep(i,1,n)cin>>a[i];dfs("",a,0);sort(v.begin(),v.end());x--;cout<<v[x]<<endl;
}
D
题意:给定两个数组a和b和数字m,可以重排a,使得 sigma(1<=i<=n)(a_i+b_i)%m 最小
思路:
贪心
发现ai和bi的范围都是小于m的
因此我们有 0<ai+bi<2m
所以 ai+bi = c 或 ai+bi = m + c (c<m)
我们的目标是减小c之和
枚举b,发现要么取a中最小的,要么取 ai= m+c -bi ,即ai中大于等于m-bi的
两者比较取min
a的元素考虑使用multiset维护
显然,这样局部贪心能获得最优解
void solve(){int n,m;cin>>n>>m;vector<int>a(n+1);rep(i,1,n)cin>>a[i];vector<int>b(n+1);rep(i,1,n)cin>>b[i];vector<int>vis(n+1);multiset<int>at;rep(i,1,n)at.insert(a[i]);sort(a.begin()+1,a.end());int ans=0;rep(i,1,n){int res=(b[i]+*(at.begin()))%m;auto it=at.lower_bound(m-b[i]);if(it!=at.end()){int res2=(b[i]+*(it))%m;if(res2<res){at.erase(it);ans+=res2;}else{at.erase(at.begin());ans+=res;}}else{at.erase(at.begin());ans+=res;}}cout<<ans<<endl;
}