bzoj 3916: friends 瞎搞
题目:
有三个好朋友喜欢在一起玩游戏,A君写下一个字符串S,B君将其复制一遍得到T,C君在T的任意位置(包括首尾)插入一个字符得到U.现在你得到了U,请你找出S.
题解:
发现字符串的长度一定为奇数.
然后发现问题变成了
\(s[0 .. mid]\)与\(s[mid+1 .. len]\)仅删除的编辑距离为1
或 : \(s[0 .. mid-1]\)与\(s[mid .. len]\)仅删除的编辑距离为1
然后我们可以联想到以前的:电子词典嘛
所以我们这道题可以直接暴力dfs查找..
不要忘记特判下标不同但本质相同的字符串.
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
const int maxn = 2000010;
char s[maxn];int ans,n,pos,del;
bool end_all1,end_all2;
void dfs1(int i,int j,bool f,int d){
if(end_all1) return;
if(i == pos+1){
del = d;
end_all1 = true;
++ ans;
return;
}
if(s[i] != s[j] || j == n){
if(f) dfs1(i+1,j,false,i);
else return;
}else{
dfs1(i+1,j+1,f,d);
if(f) dfs1(i+1,j,false,i);
}
}
void dfs2(int i,int j,bool f,int d){
if(end_all2) return;
if(i == n){
del = d;
end_all2 = true;
++ ans;
return;
}
if(s[i] != s[j] || j == pos){
if(f) dfs2(i+1,j,false,i);
else return;
}else{
dfs2(i+1,j+1,f,d);
if(f && i != pos) dfs2(i+1,j,false,i);
}
}
int main(){
read(n);
if(n % 2 == 0 || n == 1) return puts("NOT POSSIBLE");
pos = (n>>1);scanf("%s",s);
dfs1(0,pos+1,true,0);
if(s[pos] == s[0]) dfs2(pos+1,1,true,0);
if(ans == 2){
int i;
for(i=0;i<pos && s[i] == s[pos+i+1];++i);
if(i < pos) puts("NOT UNIQUE");
else for(int i=0;i<pos;++i) putchar(s[i]);
}
else if(ans == 0) puts("NOT POSSIBLE");
else{
if(del < pos){
for(int i=0;i<=pos;++i){
if(del == i) continue;
putchar(s[i]);
}
}else{
for(int i=pos;i<n;++i){
if(del == i) continue;
putchar(s[i]);
}
}
puts("");
}
getchar();getchar();
return 0;
}
人就像命运下的蝼蚁,谁也无法操控自己的人生.