ARC154 解题报告【A-D】
Atcoder Regular Contest 154
声明:代码只包含核心代码,交上去会 CE!
A - Swap Digit
设 \(a,b\) 的第 \(i\) 位分别为 \(a_i,b_i\)。由于 \(a_i\) 与 \(b_i\) 本身没有变化(只是可能交换),所以 \(a_i+b_i\) 也不变,即 \(a+b\) 不会变。
根据“和一定,差小积大”,\(a-b\) 要尽量大。不妨让 \(a\ge b\),则当 \(a_i<b_i\) 时,交换 \(a_i\) 与 \(b_i\)。
然后再膜 \(998244353\) 再乘即可。
struct ModInt
{
static const ll MOD=/*modulo number*/998244353;
ll val;
ModInt(ll v=0){val=v%MOD;}
operator ll(){return val;}
ModInt operator=(const ll v){return (*this)=ModInt(v);}
ModInt operator+(const ModInt B)const{return (val+B.val)%MOD;}
ModInt operator+=(const ModInt B){return (*this)=(*this)+B;}
ModInt operator-(const ModInt B)const{return (val-B.val+MOD)%MOD;}
ModInt operator-=(const ModInt B){return (*this)=(*this)-B;}
ModInt operator*(const ModInt B)const{return val*B.val%MOD;}
ModInt operator*=(const ModInt B){return (*this)=(*this)*B;}
};
istream& operator>>(istream &in,ModInt &A)
{
in>>A.val;A.val%=ModInt::MOD;
return in;
}
ostream& operator<<(ostream &out,const ModInt A)
{
out<<A.val;
return out;
}
int n;
string a,b;
void Solve()
{
cin>>n>>a>>b;
for(int i=0;i<n;i++)
if(a[i]<b[i])swap(a[i],b[i]);
ModInt s=0,t=0;
for(int i=0;i<a.size();i++)
s=s*(ModInt)10+(ModInt)(a[i]-'0'),t=t*(ModInt)10+(ModInt)(b[i]-'0');
cout<<s*t;
}
B - New Place
可以看出,\(S\) 的后面没有被操作的字母肯定是 \(T\) 的子序列(因为根本就没动过)。只要从后往前遍历 \(S\),用一个指针从后往前扫描 \(T\),找到最近的一个与 \(S_i\) 相同的 \(T_j\)。如果找不到,答案就是前面的字符个数。
至于无解的判定,当且仅当 \(S\) 与 \(T\) 的各个字母数量相同时有解。
int n;
string a,b;
int cnt[26][2],pos;
void Solve()
{
cin>>n>>a>>b;
for(int i=0;i<n;i++)
cnt[a[i]-'a'][0]++,cnt[b[i]-'a'][1]++;
for(int i=0;i<26;i++)
if(cnt[i][0]!=cnt[i][1])return cout<<-1,void();
pos=n-1;
for(int i=n-1;~i;i--)
{
while(pos>=0&&b[pos]!=a[i])pos--;
if(pos<0)return cout<<i+1,void();
pos--;
}
cout<<0;
}
C - Roller
解法待填。
记得多测啊!
const int N=5005;
int n,a[N],b[N],c[N<<1],d[N],cnt1,cnt2;
#define yes return cout<<"Yes"<<endl,void()
#define no return cout<<"No"<<endl,void()
void Solve()
{
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)cin>>b[i];
c[cnt1=1]=a[1];
for(int i=2;i<=n;i++)
if(a[i]!=a[i-1])c[++cnt1]=a[i];
if(a[1]==a[n]&&cnt1>1)cnt1--;
d[cnt2=1]=b[1];
for(int i=2;i<=n;i++)
if(b[i]!=b[i-1])d[++cnt2]=b[i];
if(b[1]==b[n]&&cnt2>1)cnt2--;
if(cnt2==n)
{
for(int i=1;i<=n;i++)
if(a[i]!=b[i])no;
yes;
}
if(cnt1<cnt2)no;
for(int i=1;i<cnt1;i++)c[cnt1+i]=c[i];
//for(int i=1;i<=cnt1;i++)cout<<c[i]<<" ";cout<<endl;
//for(int i=1;i<=cnt2;i++)cout<<d[i]<<" ";cout<<endl;
for(int k=1;k<=cnt1;k++)
{
bool ok=1;
for(int i=1,j=k;i<=cnt2;i++)
{
while(j<k+cnt1&&c[j]!=d[i])j++;
if(j>=k+cnt1)ok=0;
j++;
}
if(ok)yes;
}
no;
}
D - A + B > C ?
解法待填。
const int N=2005;
int n,a[N],x=1;
//true for Yes, false for No
//Pi+Pj>Pk?
bool ask(int i,int j,int k)
{
cout<<"? "<<i<<" "<<j<<" "<<k<<endl;
string res;
cin>>res;
assert(res!="-1");
return res=="Yes";
}
void ans()
{
cout<<"!";
for(int i=1;i<=n;i++)cout<<" "<<a[i];
cout<<endl;
}
typedef vector<int> V;
V emp;
V Sort(int l,int r)
{
if(l==r)
{
if(l!=x)return V(1,l);
else return emp;
}
int mid=l+r>>1;
V s1=Sort(l,mid),s2=Sort(mid+1,r),s=emp;
int t1=0,t2=0,sz1=s1.size(),sz2=s2.size();
while(t1<sz1||t2<sz2)
{
if(t1==sz1||(t2<sz2&&ask(s1[t1],x,s2[t2])))s.push_back(s2[t2]),t2++;
else s.push_back(s1[t1]),t1++;
}
return s;
}
void Solve()
{
cin>>n;
for(int i=2;i<=n;i++)
if(!ask(i,i,x))x=i;
a[x]=1;
V an=Sort(1,n);
for(int i=0;i<an.size();i++)a[an[i]]=i+2;
ans();
}