• usaco4.1.4 Cryptcowgraphy


    最后的总结,最终没有看题解,自己想出来四个剪枝,刚开始四个剪枝加上一直无法ac,正在抓狂的时候发现有个地方写错了,导致许多新的枝条,改一下,ac了,这一题也没想象中的那么难,加油。

    后记:看了题解后搜索顺序改了一下,直接导致剪枝四没有用上,发现慢的出奇,15s左右才能出解,看来剪枝四效率很高呢。

    一看就是搜索,写一下裸的过了5个点

    {ID:zhengha3
    PROG:cryptcow
    LANG:PASCAL
    }
    program aa;
    const z='Begin the Escape execution at the Break of Dawn';
    var s:string;
    i,j:longint;
    function check(s:string):boolean;
    begin
    if s=z then exit(true) else exit(false);
    end;
    procedure dfs(s:string;dep:longint);
    var i,j,k,l:longint;
    s1,s2,s3,s4:string;
    begin
    if check(s) then begin writeln(1,' ',dep);close(output);halt;end;
    l:=length(s);
    for i:=1 to l do
    if s[i]='C' then
    for j:=i+1 to l do
    if s[j]='O' then
    for k:=j+1 to l do
    if s[k]='W' then
    begin
    s1:=copy(s,1,i-1);
    s2:=copy(s,i+1,j-i-1);
    s3:=copy(s,j+1,k-j-1);
    s4:=copy(s,k+1,l);
    s1:=s1+s3;s1:=s1+s2;s1:=s1+s4;
    dfs(s1,dep+1);
    end;
    end;
    begin
    assign(input,'cryptcow.in');reset(input);
    assign(output,'cryptcow.out');rewrite(output);
    read(s);
    dfs(s,0);
    writeln(0,' ',0);
    close(output);
    end.

    留位想剪枝

    剪枝一,第一个特殊字符必须是C,最后一个特殊字符必须是W

    剪枝二,hash数组判重,不重复处理

    加上这两个剪枝第六个点大概8秒出解,继续想

    这好像是个大剪枝,剪枝三,每两个特殊字符之间的字符串必须和目标字符串有交集,即pos(s1,z)<>0;

    加上这个剪枝后又快了大概3秒钟,5s出解,看来还有更为强大的剪枝,继续想..烦..

    剪枝四,这个应该归到剪枝三上,因为我是这样循环的

    for i:=1 to l do
    if s[i]='C' then
    for j:=i+1 to l do
    if s[j]='O' then
    for k:=j+1 to l do
    if s[k]='W' then
       所以我发现如果在上一个k没有通过剪枝三话那么剩下的也通不过,直接break;

    第6个点耗时2.2s,还是超时,再相出一个剪枝估计就可以ac了,继续,恶心..

    突然发现有一点写错了,感觉剪枝四要分情况,等下再写,用前三个剪枝,过到第八个点,剪枝四应该是可以用的,感觉要以o为界限,让我再仔细想一下

    加上剪枝四了,第六个点确实变快了,第八个点根本没用上剪枝四。

    认真检查一下,发现有一个地方写脑残了,导致了很多大枝条,改了一下,ac了,成就感颇高,这四个剪枝全是自己想的,yes..

    {ID:zhengha3
    PROG:cryptcow
    LANG:PASCAL
    }
    program aa;
    const z='Begin the Escape execution at the Break of Dawn';
    seed=31;
    var s:string;
    i,j:longint;
    hash:array[0..1200007] of boolean;
    a:array[1..29] of longint;
    function bkdhash(s:string):longint;
    var i:longint;
    begin
    bkdhash:=0;
    for i:=1 to length(s) do
    bkdhash:=(bkdhash*seed+ord(s[i]))and $FFFFFFF;
    end;
    function check(s:string):boolean;
    begin
    if s=z then exit(true) else exit(false);
    end;
    function cut1(s:string):boolean;
    var i:longint;
    begin
    for i:=1 to length(s) do
    if (s[i]='C') or (s[i]='W') or (s[i]='O') then
    if s[i]<>'C' then exit(false) else break;
    for i:=length(s) downto 1 do
    if (s[i]='C') or (s[i]='W') or (s[i]='O') then
    if s[i]<>'W' then exit(false) else break;
    exit(true);
    end;
    function cut2(s:string):longint;
    var s1:string;
    sum:longint;
    begin
    a[1]:=0;sum:=1;
    for i:=1 to length(s) do if (s[i]='C') or (s[i]='O') or (s[i]='W') then begin inc(sum);a[sum]:=i;end;
    inc(sum);a[sum]:=length(s)+1;
    for i:=1 to sum-1 do
    begin
    s1:=copy(s,a[i]+1,a[i+1]-a[i]-1);
    if (pos(s1,z)=0) and (s1<>'') then exit(a[i+1]);
    end;
    exit(-1);
    end;
    procedure dfs(s:string;dep:longint);
    var i,j,k,l,con:longint;
    s1,s2,s3,s4,s5:string;
    pd:boolean;
    begin
    if check(s) then begin writeln(1,' ',dep);close(output);halt;end;
    l:=length(s);
    for i:=1 to l do
    if s[i]='C' then
    begin
    s1:=copy(s,1,i-1);
    if cut2(s1)<>-1 then
    break;
    for j:=i to l do
    if s[j]='O' then
    begin
    s1:=copy(s,i,j-i-1);
    if cut2(s1)<>-1 then
    break;
    for k:=j+1 to l do
    if s[k]='W' then
    begin
    s1:=copy(s,1,i-1);
    s2:=copy(s,i+1,j-i-1);
    s3:=copy(s,j+1,k-j-1);
    s4:=copy(s,k+1,l);
    s1:=s1+s3;s1:=s1+s2;s1:=s1+s4;
    con:=bkdhash(s1) mod 1200007;
    if cut1(s1)=false then continue;
    if cut2(s1)<>-1 then break;
    if hash[con]=false then begin dfs(s1,dep+1);hash[con]:=true;end else continue;
    end;
    end;
    end;
    end;
    begin
    assign(input,'cryptcow.in');reset(input);
    assign(output,'cryptcow.out');rewrite(output);
    read(s);
    if cut1(s)=false then begin writeln(0,' ',0);halt;close(output);end;
    dfs(s,0);
    writeln(0,' ',0);
    close(output);
    end.
  • 相关阅读:
    C89和C99区别--简单总结
    C语言 值传递和地址传递
    对于.h文件和.c文件
    C语言-------多文件编译
    数据结构之第二章线性表
    数据结构之第一章一些概念
    JS-prototype的掌握
    JS-return的使用
    分分钟搞懂JS-闭包函数
    JS-面向对象-封装
  • 原文地址:https://www.cnblogs.com/nbalive2001/p/2597415.html
Copyright © 2020-2023  润新知