用Perl解答一道小学数学题


ps: 现在的小学生真是天才,一道小学数学题都足够你折腾的。

一道小学数学题

大概意思是这样:

1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1

4*4,把其中6个1替换成0,使得横竖1的个数都是偶数,一共有几种,并打印出来。

原题是在 azalea says 的博客看到的,她是用Python的穷举法解答出来的,Python我是不懂的了,有兴趣的你就过去围观吧。一道小学数学题

看到后我就想尝试着用Perl来解答了,也就再次证明我对Perl还是没入门的,加紧学习啊!! 解答的思路基本上是借鉴了 azalea says 的,把十进制转为二进制。

Perl的穷举法

下面是用Perl的穷举法(还复习了一下穷举法的思路)来解答的,答案96

注:我已经尽最大努力的简化代码了,不过 is_even 这里还是有再简化的空间的。再一次证明我学艺不精啊。脚本解题速度的也不咋地。

#!/usr/bin/perl -w

$n = 4;
$count = 0;

sub SUM {
    my $sum = 0;
    map {$sum += $_} @_;
    return $sum;
}

sub int2b {
    my ($j) = @_;
    push ( my @a, (split '', sprintf("%016b", $j)) );
    return @a;
}

sub is_even {
    foreach  (0..$n-1) {
        if ( &SUM(@_[$_*$n..$n-1+$_*$n]) % 2 || &SUM(@_[$_,$n+$_,$n*2+$_,$n*3+$_]) % 2 ) {
            $re = 0;
            last;
        } else {
            $re = 1;
        }
    }
    return $re;
}

foreach (1..2**($n*$n)) {
    @_ = &int2b($_);
    if ( &is_even(@_) && &SUM(@_) == '10' ) {
         $count++;
         print "----",$count,"\n";
         print splice(@_,0,4),"\n" while @_;
    }
}

数值赋值法

还有一个高手是用 数值赋值法 解答出来的。贴出来供大家学习一下啊。高手出手,偶们小虾坐下来多多学习。

#!/usr/bin/perl -w
## Author: BENM ##

use strict;

my @a=(0,1,2,3);
my @matrix=([0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]);
my @combo=([1,0,0],[0,1,0],[0,0,1]);
my @D=([0,1,2],[0,2,1],[1,0,2],[1,2,0],[2,0,1],[2,1,0]);
my $count=0;

foreach my $i (@a) {
 foreach my $j (@a) {
 my @out=@matrix;
 @{$out[$i]}=(1,1,1,1);
 map{$_->[$j]=1}@out;

 my @B=@a;
 my @C=@a;
 splice(@B,$i,1);
 splice(@C,$j,1);

  for (my $k=0;$k<@D ;$k++) {
   my $m=0;
    foreach my $x(@B) {
    my $y=$D[$k][$m];
    $m++;
    @{$out[$x]}[@C]=@{$combo[$y]};
   }
   $count++;
   print "----$count\n";
   foreach  (@out) {
    print join " ",@$_,"\n";
   }
  }
 }
}

20条回应:“用Perl解答一道小学数学题”

  1. 把6个1替换成0使得横竖1的个数都为偶数?
    要么0 0 1 1
    要么0 1 1 0
    要么0 1 0 1
    要么0 1 1 0
    要么1 0 0 1
    要么1 0 1 0
    要么1 1 0 0
    要么1 1 1 1

    如果某一行的一个1换成0 这一样就不满足行中偶数个1的要求
    如果前三行的两个1换成0 。。。。。。
    不知道是题的问题还是我没搞明白题目要求