• BZOJ1562: [NOI2009]变换序列


    1562: [NOI2009]变换序列

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 1148  Solved: 599
    [Submit][Status]

    Description

    Input

    Output

    Sample Input

    5
    1 1 2 2 1

    Sample Output

    1 2 4 0 3

    HINT

    30%的数据中N≤50;
    60%的数据中N≤500;
    100%的数据中N≤10000。

    Source

    题解:

    不愧是NOI的题目,果然是好题。

    具体题解建BYVOID的博客:https://www.byvoid.com/blog/noi-2009-transform/ 

    讲的非常清楚,个人认为第二种解法是容易想到的,这其中有很多细节需要注意:

    1.在寻找最小字典序的时候,加入一个当前查询点,使得在寻找增广路的时候如果x<=cur 那么返回false

       这是我在思考的时候没有想到的,就是如何能让后面的点在更新解的时候不妨碍到前面已经更新过的点

       这是一个非常好的思路,十分巧妙

    2.我在刚开始想的时候想到每个点一定有两个匹配点吗?答案是不一定的

       于是我在程序中进行了进一步的验证,但在后面的解题中我并没有再考虑a[i]=-1 or b[i]=-1的情况,同样得到了正确的答案

       应该是cur的限制卡掉了这些-1

    代码:

     1 const maxn=10000+100;maxm=20000+100;
     2 type node=record
     3      go,next:longint;
     4      end;
     5 var e:array[0..maxm] of node;
     6     head,a,b,px,py,c:array[0..maxn] of longint;
     7     v:array[0..maxn] of boolean;
     8     cur,i,n,tot,ans,tmp:longint;
     9     procedure swap(var x,y:longint);
    10      var t:longint;
    11          begin
    12          t:=x;x:=y;y:=t;
    13          end;
    14 
    15 procedure insert(x,y:longint);
    16  begin
    17  inc(tot);
    18  e[tot].go:=y;e[tot].next:=head[x];head[x]:=tot;
    19  end;
    20 function find(x:longint):boolean;
    21  var i,y:longint;
    22  begin
    23  if x<=cur then exit(false);
    24  i:=head[x];
    25  while i<>0 do
    26   begin
    27   y:=e[i].go;
    28   if not(v[y]) then
    29    begin
    30    v[y]:=true;
    31    if (py[y]=-1) or (find(py[y])) then
    32     begin
    33     py[y]:=x;
    34     px[x]:=y;
    35     exit(true);
    36     end;
    37    end;
    38   i:=e[i].next;
    39   end;
    40  exit(false);
    41  end;
    42 procedure init;
    43  begin
    44  readln(n);
    45  for i:=0 to n-1 do
    46    begin
    47    read(c[i]);
    48    a[i]:=(i+c[i]) mod n;
    49    if n-abs(a[i]-i)<c[i] then a[i]:=-1;
    50    b[i]:=(i+n-c[i]) mod n;
    51    if abs(b[i]-i)<c[i] then b[i]:=-1;
    52    if a[i]>b[i] then swap(a[i],b[i]);
    53    if a[i]<>-1 then insert(i,a[i]);
    54    if b[i]<>-1 then insert(i,b[i]);
    55    writeln(a[i],' ',b[i]);
    56    end;
    57  end;
    58 procedure main;
    59  begin
    60  for i:=0 to n-1 do py[i]:=-1;
    61  cur:=-1;
    62  for i:=0 to n-1 do
    63   begin
    64   fillchar(v,sizeof(v),false);
    65   if find(i) then inc(ans);
    66   end;
    67  if ans<>n then begin writeln('No Answer');exit;end;
    68  fillchar(v,sizeof(v),false);
    69  for i:=0 to n-1 do
    70   begin
    71   if px[i]<>a[i] then
    72     begin
    73     cur:=i;
    74     fillchar(v,sizeof(v),false);
    75     tmp:=py[a[i]];
    76     py[a[i]]:=i;
    77     py[b[i]]:=-1;
    78     v[a[i]]:=true;
    79     if find(tmp) then
    80       begin
    81        px[i]:=a[i]
    82       end
    83     else
    84       begin
    85        py[a[i]]:=tmp;
    86        py[b[i]]:=i;
    87       end;
    88     end;
    89   end;
    90  write(px[0]);for i:=1 to n-1 do write(' ',px[i]);
    91  end;
    92 begin
    93  assign(input,'input.txt');assign(output,'output.txt');
    94  reset(input);rewrite(output);
    95  init;
    96  main;
    97  close(input);close(output);
    98 end.    
    View Code
  • 相关阅读:
    MySQL简单实现多字段模糊查询【转】
    PHP检测URL格式是否正确域名地址是否有效【转】
    php如何判断IP为有效IP地址【转】
    PHP isset() 函数使用【转】
    php生成唯一随机码【转】
    php判断一个值是否在数组中【转】
    Win10系统gpedit.msc文件找不到,如何解决【转】
    B
    【金色】种瓜得瓜,种豆得豆 Gym
    J
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/3911506.html
Copyright © 2020-2023  润新知