zoukankan      html  css  js  c++  java
  • dvd的舞女

    【题目描述】

     众所周知,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.
  • 相关阅读:
    JS基础语法---函数练习part3---4个练习
    JS基础语法---函数练习part2---10个综合练习(运用:循环/数组/函数)
    JS基础语法---函数练习part1---5个练习
    JS基础语法---函数---介绍、定义、函数参数、返回值
    JS基础语法---冒泡顺序
    JS基础语法---数组案例---9个练习
    JS基础语法---for循环遍历数组
    Python小技巧:使用一行命令把你的电脑变成服务器
    目前最全的Python的就业方向
    这十个Python常用库,学习Python的你必须要知道!
  • 原文地址:https://www.cnblogs.com/wuminyan/p/4746777.html
Copyright © 2011-2022 走看看