【题目描述】
众所周知,dvd是一个爱做梦的好孩子。
但是不知道为什么最近dvd总是梦到一群舞女
众所周知,dvd是一个爱琢磨的好孩子。
但是不知道为什么dvd最近一直想不明白为什么
终于dvd发现了梦境的规律,所有舞女在一个n*n的大方格上跳舞,大方格上的一些位置可以占人,其他位置不行。每时每刻都有一个舞女在一个可以占人的位置跳舞。
过一段时间,每个舞女都会对于自己前方,左方,右方三分方向看一下,如果有且仅有一个位置可以站人,她就会朝哪个方向转身并(如果是前面就不转身了)移动到那个位置,否则就会因为无路可走或者选择困难综合征挂掉。也不能有两个舞女同时出现在一个位置上(这样她们会打架).
但是同样的,再不能站人的位置,会有一堆跳舞机器人做着和舞女同样的事情(smg?)
dvd是一个友善的好孩子,众所周知。所以dvd非常不希望看到舞女或者机器人挂掉或者打架。
Dvd是一个聪明的好孩子,众所周知。所以dvd想要知道,如果用E表示可以站立(这里有舞女),.(英文的句点,编码46) 表示不可以站立(这里有机器人),那么字典序第k大的合法舞台。如果合法的不存在k个,输出-1否则输出方案
【输入格式】
读入n,k
【输出格式】
如果k个及以上的方案,输出字典序第k的方案,否则输出-1
【样例输入1】
4 1
【样例输出1】
....
.EE.
.EE.
....
【样例输入2】
5 5
【样例输出2】
-1
【数据范围和约定】
对于30%的数据 n<=10
对于另外30%的数据,k<=10
对于100%的数据n<=100,k<=10^15
【解题思路】
这是大神的原创题,刚开始看我觉得是分治,再看觉得是图论,最后你告诉我是搜索,你逗我玩呢?
这个题你会发现一个问题,只有每一个点的四周总会有两个点与他相同才能满足条件,其实也很好理解,舞女或者机器人从一个方向跳过来,在跳向另一个方向,所以只要确定第一行就能确定全部,问题的关键就是如何确定第一行,老湿告诉我你只需要把k-1的二进制求出来,个数*2,然后从后往前填把1填'E',0填‘.’,为什么?老湿告诉我我你多花几个图就知道了。。。呵呵哒,大神就是大神,不多解释
默默地贴一下代码
1 program dancer; 2 const dx:array[1..4] of longint=(1,0,-1,0); 3 dy:array[1..4] of longint=(0,1,0,-1); 4 var f:array[1..4,1..4] of longint; 5 i,j,k,n:Longint; 6 a:array[1..100] of longint; 7 function cha(w:longint):longint; 8 begin 9 if w=1 then exit(0); 10 if w=0 then exit(1); 11 end; 12 function pd:boolean; 13 var i,j:longint; 14 begin 15 for i:=1 to n do 16 for j:=1 to n do if f[i,j]=-1 then exit(false); 17 exit(true); 18 end; 19 procedure print; 20 var i,j:longint; 21 begin 22 for i:=1 to n do 23 begin 24 for j:=1 to n do write(f[i,j]); 25 writeln; 26 end; 27 halt; 28 end; 29 30 procedure dfs(x,y:longint); 31 var i,k,j,sum:longint; 32 begin 33 34 for i:=1 to 4 do 35 if (x+dx[i]>=1) and (dy[i]+y>=1) and(y+dy[i]<=n) and(x+dx[i]<=n) and(f[x+dx[i],y+dy[i]]=-1) then 36 begin 37 for j:=0 to 1 do 38 begin 39 sum:=0; 40 f[x+dx[i],y+dy[i]]:=j; 41 for k:=1 to 4 do 42 if (x+dx[k]>=1) and (dy[k]+y>=1) and(y+dy[k]<=n) and(x+dx[k]<=n) then 43 if f[x+dx[k],y+dy[k]]=f[x,y] then inc(sum); 44 if sum>2 then continue else dfs(x+dx[i],dy[i]+y); 45 if pd then print; 46 f[x+dx[i],y+dy[i]]:=-1; 47 end; 48 49 end; 50 end; 51 begin 52 read(n,k); 53 fillchar(f,sizeof(f),byte(-1)); 54 k:=k-1; 55 while k>0 do 56 begin 57 inc(i); 58 a[i]:=k mod 2; 59 k:=k div 2; 60 end; 61 if (n mod 2<>0) or (2*i>n) then 62 begin 63 write('-1'); 64 halt; 65 end; 66 for j:=i downto 1 do 67 begin 68 f[1,j*2]:=a[j]; 69 f[1,j*2-1]:=a[j]; 70 end; 71 for i:=1 to n do if f[1,i]=-1 then f[1,i]:=0; 72 dfs(1,1); 73 74 for i:=1 to n do 75 begin 76 for j:=1 to n do 77 if f[i,j]=1 then write('E') else write('.'); 78 writeln; 79 end; 80 end.