http://contest-hunter.org:83/contest/SRM%2008
A
解法1:利用数据随机的特点,10位及以下的进行dfs判断,以上的直接输出Y。不过这也有反例,0111111111111111111111111111111111是N,但还是合理AC啦。
var s:string; var i,j,a1,b,k,num,n:longint; var ss:array[0..10000] of string; var y,a:array[0..10000] of longint; var r:array[0..10000] of boolean; procedure dfs(d:longint); var i:longint; begin if d>n then begin inc(num);ss[num]:=''; for i:=1 to n do ss[num]:=ss[num]+s[a[i]];y[num]:=1; for j:=1 to num-1 do if ss[num]=ss[j] then begin inc(y[j]);break;end; exit; end; for i:=a[d-1]+1 to length(s) do if not r[i] then begin r[i]:=true;a[d]:=i; dfs(d+1); r[i]:=false; end; end; begin readln(s);if length(s)>10 then begin writeln('Y');exit;end; for i:=1 to length(s) do if s[i]='1' then inc(a1) else inc(b); if (a1=2) or (b=2) then begin writeln('Y');exit;end; for n:=2 to length(s)-1 do begin num:=0;fillchar(y,sizeof(y),0); dfs(1); for i:=1 to num do if y[i]=2 then begin writeln('Y');exit;end; end; writeln('N'); {for i:=2 to length(s)-1 do begin ss[1]:=s;;y[1]:=1; delete(ss[1],i+1,length(s)-i); for j:=2 to length(s)-i+1 do begin ss[j]:=ss[j-1];delete(ss[j],1,1);ss[j]:=ss[j]+s[j+i-1]; y[j]:=1; for k:=1 to j-1 do if ss[j]=ss[k] then begin inc(y[k]);break;end; end; //for j:=1 to length(s) do writeln(ss[j]); for j:=1 to length(s)-i+1 do if y[j]=2 then begin writeln('Y');exit;end; end; writeln('N'); } end.
解法2:第一种情况:0或1只出现2次的当然成立,直接输出Y。
第二种情况:把字符串分割成三部分,如果成立以下条件:子集s1+00/11+子集s2,即输出Y。因为要找子序列,所以子集s1+0/1+子集s2必定只出现两次。例如101001,子集s1=101,子集s2=1,中间00,发现子序列10101出现两次。
var s:ansistring; var i,a,b:longint; var c:char; begin readln(s); for i:=1 to length(s) do if s[i]='1' then inc(a) else inc(b); s:=''+s+'';c:='N'; if (a=2) or (b=2) then c:='Y'; for i:=2 to length(s)-1 do if (s[i]=s[i+1]) and (s[i-1]<>s[i]) and (s[i+1]<>s[i+2]) then begin c:='Y';break;end; writeln(c); end.
【未完待续】