Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1003448
  • 博文数量: 150
  • 博客积分: 3017
  • 博客等级: 少校
  • 技术积分: 3829
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-19 14:40
个人简介

Now in Baidu WISE team

文章分类

全部博文(150)

文章存档

2014年(8)

2013年(31)

2012年(111)

分类: Python/Ruby

2012-04-17 18:34:49

题目:
输出(2n+1)幻方的所有可能的排列
 
目前效率还很低。 5阶就要算好久。算法有些问题,成了枚举所有可能性了
 

点击(此处)折叠或打开

  1. my $size = 3;
  2. my @pool = (1..$size*$size);
  3. my @lines;
  4. my @rows;


  5. my $sum = $size*($size*$size +1)/2;

  6. sub OutputSquare{
  7.     for(@_){
  8.         print "@{$_} \n";
  9.     }
  10.     print "\nxxxxxxxxxxxxxxxxxxxxxxxxxxx\n";
  11. }

  12. sub IsDuplicate{
  13.     my ($reffset, $refeset) = @_;
  14.     my @fset = @{$reffset};
  15.     my @eset = @{$refeset};
  16.     my $key = $eset[($size-1)/2];
  17.     for(@fset){
  18.         my @tmp = @{$_};
  19.         if($tmp[($size -1)/2] eq $key){
  20.             return 1;
  21.         }
  22.     }
  23.     return 0;
  24. }


  25. sub BuildLine{
  26.     my ($refline, $fresult,@pool) = @_;
  27.     my @line = @{$refline};

  28.     if(@line <$size){
  29.         my $i = @line;
  30.         for my $sv (@pool){
  31.             my @linecopy = @line;
  32.             $linecopy[$i] = $sv;
  33.             BuildLine(\@linecopy, $fresult, grep {$_ ne $sv} @pool);
  34.         }
  35.     }
  36.     else{
  37.         if(IsValidRow(@{$refline})){
  38.             push(@{$fresult}, $refline);
  39.         }
  40.     }
  41. }

  42. sub BuildSquare{
  43.     my ($refrows, $fresult, @pool) =@_;
  44.     my @rows = @{$refrows};

  45.     if(@rows < $size){
  46.         my $i = @rows;
  47.         for my $sv( @pool){
  48.             my @rowscopy = @rows;
  49.             $rowscopy[$i] = $sv;
  50.             @copypool = GetLeftRows(\@pool,\@rowscopy);
  51.             BuildSquare(\@rowscopy, $fresult,@copypool);
  52.         }
  53.     }
  54.     else{
  55.         if(IsValidSquare(@$refrows)){
  56.             push (@{$fresult} , $refrows);
  57.         }
  58.     }

  59.     
  60. }
  61. sub IsValidSquare{
  62.     my @rows = @_;
  63.     my @sum;

  64.     for $r (0..$size-1){
  65.         my @row = @{$rows[$r]};
  66.         for $c (0..$size-1){
  67.             $sum[$c]+=$row[$c];
  68.         }
  69.         $sum[$size]+=$row[$r];
  70.         $sum[$size+1]+=$row[$size - $r -1];
  71.     }
  72. #    print "checking: @sum \n";

  73.     return 0 if( grep {$_ ne $sum} @sum);
  74.     return 1;
  75.     
  76. }

  77. sub IsValidRow{
  78.     my @data = @_;
  79.     my $tsum = 0;
  80.     for(@data){
  81.         $tsum += $_;
  82.     }
  83.     $tsum == $sum ? 1:0;
  84. }

  85. sub GetLeftRows{
  86.     my ($refAllrow, $refrows) = @_;
  87.     my @rows = @$refrows;
  88.     my @allrow = @$refAllrow;
  89.     my @tmppool = @pool;
  90.     for my $row (@rows){
  91.         for my $cell (@$row){
  92.             @tmppool = grep {$_ ne $cell} @tmppool;
  93.         }
  94.     }
  95.     my @result;
  96.     for my $pr (@allrow){

  97.         my %hash;
  98.         foreach (@$pr, @tmppool){
  99.             $hash{$_}++;
  100.         }
  101.         if((keys(%hash) == @tmppool)){
  102.             push(@result,$pr);
  103.         }

  104.     }
  105.     my $count = @result;
  106.     return @result;
  107. }

  108. sub Square{
  109.     my (@lineset) = @_;
  110.     my @fs = ();
  111.     my $index = 0;
  112.     for my $l(@lineset){
  113.         $index++;
  114.         my @set = ($l);
  115.         my @tmplineset = @lineset;
  116.         BuildSquare(\@set, \@fs, GetLeftRows(\@tmplineset, \@set));
  117.     }

  118.     return @fs;
  119. }

  120. for my $i (@pool){
  121.     my @r = ($i);
  122.     BuildLine(\@r, \@lines, grep{$_ ne $i} @pool);
  123. }

  124. my $pos = @lines;

  125. #sleep 20;
  126. my @final = Square(@lines);
  127. foreach(@final){

  128.     OutputSquare(@{$_});
  129.     IsValidSquare(@{$_});

  130. }



阅读(1126) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~