Perl算法 每日一题3

更难的数独

@sd =(['8','.','.','.','.','.','.','.','.'],
     ['.','.','3','6','.','.','.','.','.'],
     ['.','7','.','.','9','.','2','.','.'],
     ['.','5','.','.','.','7','.','.','.'],
     ['.','.','.','8','4','5','7','.','.'],
     ['.','.','.','1','.','.','.','3','.'],
     ['.','.','1','.','.','.','.','6','8'],
     ['.','.','8','5','.','.','.','1','.'],
     ['.','9','.','.','.','.','4','.','.']
);

$num ='1,2,3,4,5,6,7,8,9';
LOOP:
undef @si;
undef @sj;
undef @sk;
undef @sv;
for($i=0;$i<=8;$i++){
    for($j=0;$j<=8;$j++){
        if($sd[$i][$j] eq '.'){
            @v = &V($i,$j,$num);
            if($#v == 0){
                $sd[$i][$j] = $v[0];
            }else{
            push(@si,$i);
            push(@sj,$j);
            push(@sk,$#v);
            push(@sv,join("\,",@v));                
            }
            
        }
    }    
}

 

@all = ([@si],[@sj],[@sk],[@sv]);
@xxx = sort{$all[2]->[$a] <=> $all[2]->[$b]}0..$#{$all[0]};
if($#sk >= 0){
$i = 0;
$ii = $#sk;
while ($i <= $ii){
    $xxx = $xxx[$i];
    $uu = "$si[$xxx]$sj[$xxx]";
    $c{$uu} = 0;

&S;    
    $i++;
}    


for(my $i=0;$i<=8;$i++){
    for(my $j=0;$j<=8;$j++){
        print"$sd[$i][$j] ";
    }
    print"\n";
}
 print"\n";

}

sub S{

@vv = &V($si[$xxx],$sj[$xxx],$sv[$xxx]);    
if($#vv >= $c{$uu}){    
$sd[$si[$xxx]][$sj[$xxx]] = $vv[$c{$uu}];
    if($i== 0 && $#vv == $c{$uu}){
    goto LOOP;
    }
}else{
$sd[$si[$xxx]][$sj[$xxx]] = '.';    
$i--;
$xxx = $xxx[$i];
$sd[$si[$xxx]][$sj[$xxx]] = '.';    
$uu = "$si[$xxx]$sj[$xxx]";
$c{$uu}++;
&S;
}    
}

sub V{
    my @v;
    my $i = $_[0];
    my $j = $_[1];
    my $num =$_[2];
    my @num =split/\,/,$num;
            foreach $n(@num){
                $x = &X($i,$n);
                $y = &Y($j,$n);
                $xy = &XY($i,$j,$n);
#                print"$i $j $x $y $xy $n\n";
                if($x eq 'no' && $y eq 'no' && $xy eq 'no'){
                    push(@v,$n);
                }
                
            }
            return @v;    
}
                
sub X{
    $va = 'no';
for($o=0;$o<=8;$o++){
    if($_[1] eq $sd[$_[0]][$o]){
        $va = "yes";
        last;
    }
}
return $va;    
}
sub Y{
    $va = 'no';
for($o=0;$o<=8;$o++){
    if($_[1] eq $sd[$o][$_[0]]){
        $va = "yes";
        last;
    }
}
return $va;    
}

sub XY{
$va = 'no';
$is = ($_[0] - $_[0] % 3);
$ie = $is + 2;
$js = ($_[1] - $_[1] % 3);
$je = $js + 2;
for($o=$is;$o<=$ie;$o++){
    for($q=$js;$q<=$je;$q++){
        if($_[2] eq $sd[$o][$q]){
            $va = "yes";
            last;
        }
    }
}
return $va;    
}

 

 

结果

8 1 2 7 5 3 6 4 9 
9 4 3 6 8 2 1 7 5 
6 7 5 4 9 1 2 8 3 
1 5 4 2 3 7 8 9 6 
3 6 9 8 4 5 7 2 1 
2 8 7 1 6 9 5 3 4 
5 2 1 9 7 4 3 6 8 
4 3 8 5 2 6 9 1 7 
7 9 6 3 1 8 4 5 2 

运行时间72秒

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值