A. Three Strings
题意:给出三个长度相等的字符串a,b,c,对于每一位a或b中的一个和c交换,是否存在使得a,b相等的情况。
思路:直接枚举c的每一位是否和a或b相同,相同则和不相同的那个交换,没有相同的则无解
#include<bits/stdc++.h>
using namespace std;
string a,b,c;
void solve(){
for(int i=0;i<(int)a.size();++i){
if(a[i]==c[i]||b[i]==c[i]) continue;
else {
cout<<"NO
";
return ;
}
}
cout<<"YES
";
}
int main(){
int T;
cin>>T;
while(T--){
cin>>a>>b>>c;
solve();
}
return 0;
}
B. Motarack's Birthday
题意:给出有n个数字的序列,数字是-1表示需要被替换,求找到一个k替换所有-1使得每个相邻数字之间的绝对值差最大的最小。
思路:三分枚举k,因为(x=k,y=绝对值的差)可以构成一个凹形的函数。应该也可以二分枚举绝对值,不过太难实现了。
#include<bits/stdc++.h>
using namespace std;
int a[100010],b[100010],n;
int check(long long k){
for(int i=1;i<=n;++i){
if(a[i]==-1) b[i]=k;
}
int Max=0;
for(int i=1;i<=n-1;++i){
Max=max(abs(b[i]-b[i+1]),Max);
}
return Max;
}
int main(){
int T;
cin>>T;
while(T--){
cin>>n;
for(int i=1;i<=n;++i){
cin>>a[i];
b[i]=a[i];
}
long long l=0,r=1e9;
int m=1e9,k;
for(int i=1;i<=100;++i){
long long ll=(l*2+r)/3;
long long rr=(l+r*2)/3;
int resl=check(ll);
int resr=check(rr);
if(resl>resr){
l=ll;
m=resr;
k=rr;
}
else {
r=rr;
m=resl;
k=ll;
}
}
cout<<m<<" "<<k<<"
";
}
return 0;
}
C. Ayoub's function
题意:用m个'1',n-m个'0'构造一个串,使得包含'1'的子串尽可能的多。例如:
"01010" 有12个子串包含'1':(1,2),(1,3),(1,4),(1,5),(2,2),(2,3),(2,4),(2,5),(3,4),(3,5),(4,4),(4,5)。
思路:容易想到让'1'的位置尽量均匀的分开答案最大,但是分开后子串的数量统计有点困难。正难则反,我们去用所有子串的数量减去全'0'串的数量得到的就是包含'1'的子串数量。(长度为n的串具有n*(n+1)/2个子串)
#include<bits/stdc++.h>
using namespace std;
int n,m;
void solve(){
long long ans=1ll*(n+1)*n/2;
n=n-m; //0的数量
m=m+1;//全0串数量
long long a=n/m,b=n%m ;//每个串最少有a个0,b个串有a+1个0
ans=ans-a*(a+1)/2*(m-b)-(a+1)*(a+2)/2*b;
cout<<ans<<'
';
}
int main(){
int T;
cin>>T;
while(T--){
cin>>n>>m;
solve();
}
return 0;
}
D. Time to Run
题意:在一个如图的地图中每个格子到相邻的格子都有两个方向的边,求从是否存在从(0,0)出发,且每条边只有一次的共走k的方案,如果有按[次数-移动]的格式输出,输出不能超过3000行,移动不超过4个字符。
思路:模拟题。首先找到一个可以把则(4nm−2n−2m)的方法,就是先向右走到最后一列,再向下向上向左,一直走到第一列,然后向下继续这样走,直到走完最后一行后还剩下所有行第一列的向上的边没走,那么最后还回到了(0,0)。剩下的就是做模拟了。
#include<bits/stdc++.h>
using namespace std;
struct ac{
string s;
int t,l;
int id;
};
vector<ac> v;
int main(){
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
int tot=4*m*n-2*n-2*m;
if(tot<k){
puts("NO");
}
else {
string tdur="DUL";
for(int i=1;i<n;++i){
if(m-1!=0){
v.push_back((ac){"R",m-1,1,1});
v.push_back((ac){tdur,m-1,3,2});
}
if(n!=1)
v.push_back((ac){"D",1,1,3});
}
if(m-1!=0){
v.push_back((ac){"R",m-1,1,4});
v.push_back((ac){"L",m-1,1,5});
}
if(n!=1)
v.push_back((ac){"U",n-1,1,6});
tot=0;
puts("YES");
int res=0;
tot=0;
for(int i=0;i<v.size();++i){
tot+=v[i].t*v[i].l;
if(tot<=k){
++res;
}
else {
tot-=v[i].t*v[i].l;
int gap=k-tot;
if(v[i].id==1){
res++;
}
else if(v[i].id==2){
if(gap/3>0){
res++;
}
if(gap-gap/3*3>0){
res++;
}
if(gap-gap/3*3>1){
res++;
}
}
else if(v[i].id==3){
res++;
}
else {
res++;
}
break;
}
if(tot==k) {
break;
}
}
cout<<res<<'
';
tot=0;
for(int i=0;i<v.size();++i){
tot+=v[i].t*v[i].l;
if(tot<=k){
++res;
cout<<v[i].t<<" "<<v[i].s<<endl;
}
else {
tot-=v[i].t*v[i].l;
int gap=k-tot;
if(v[i].id==1){
res++;
cout<<gap<<" R
";
}
else if(v[i].id==2){
if(gap/3>0){
cout<<gap/3<<" DUL
";
res++;
}
if(gap-gap/3*3>0){
cout<<"1 D
";
res++;
}
if(gap-gap/3*3>1){
cout<<"1 U
";
res++;
}
}
else if(v[i].id==3){
res++;
cout<<"1 D
";
}
else {
cout<<gap<<" "<<v[i].s;
}
break;
}
if(tot==k) {
break;
}
}
}
return 0;
}