P7814 「小窝 R3」心の記憶
提供一个最劣解
你们几十毫秒跑完的东西,我要几百毫秒。
显然,以下几种情况是无解的:
-
。
-
。
-
01。 -
10。
特判一下就好了。
注:下文提到的相反数字指的是: 的相反数字是 , 的相反数字是 。
为了保证子序列相同,我们先令答案 为 。
可是这样 的前缀和 就相等了,于是我们把 的最后一个字符变成相反的数字。
然后在末尾插入剩下 个字符。
插入第 个字符 时我们采取如下贪心策略:
-
如果 ,则加入 的相反数字。
-
否则,加入 。
也就是说,如果加入 不符合要求,就加入它的相反数字。
然而这样过不了以下两种情况:
-
000000……1 -
111111……0
怎么办呢?其实加入操作在前面和在后面是一样的,我们把这个 翻转,打上标记,按前面的求一遍,对照标记反着输出就可以了。
#include<bits/stdc++.h>
using namespace std;
int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
void write(int x)
{
if(x<0)
putchar('-'),x=-x;
if(x>9)
write(x/10);
putchar(x%10+'0');
}
int t,n,m;
string s,s1,s2;
bool fl;
char f(char c){//求c的相反数字
if(c=='0')
return '1';
else
return '0';
}
int q0(){//0的个数
int ans=0;
for(int i=0;i<s.size();i++)
if(s[i]=='0')
ans++;
return ans;
}
int main()
{
t=read();
while(t--){
n=read();
m=read();
cin>>s;
if(n==m||n==1||s=="01"||s=="10"){//无解特判
puts("-1");
continue;
}
fl=0;
if((q0()==1&&s[n-1]=='0')||(q0()==n-1&&s[n-1]=='1'))
{
for(int i=0;i<n/2;i++)
swap(s[i],s[n-1-i]);
fl=1;//打上标记
}
s1=s2=s.substr(0,n-1);
for(int i=0;i<=m-n;i++){
if(s1.substr(i,n-1)==s2)
s1+=f(s[n-1]);
else
s1+=s[n-1];
}
if(fl){
for(int i=s1.size()-1;i>=0;i--)
putchar(s1[i]);
}
else
for(int i=0;i<s1.size();i++)
putchar(s1[i]);
putchar('\n');
}
return 0;
}

浙公网安备 33010602011771号