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\n";
return ;
}
}
cout<<"YES\n";
}
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<<"\n";
}
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<<'\n';
}
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<<'\n';
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\n";
}
else if(v[i].id==2){
if(gap/3>0){
cout<<gap/3<<" DUL\n";
res++;
}
if(gap-gap/3*3>0){
cout<<"1 D\n";
res++;
}
if(gap-gap/3*3>1){
cout<<"1 U\n";
res++;
}
}
else if(v[i].id==3){
res++;
cout<<"1 D\n";
}
else {
cout<<gap<<" "<<v[i].s;
}
break;
}
if(tot==k) {
break;
}
}
}
return 0;
}