magic square(幻方、宫格)解法实现(全)

清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>

#this is for solving the problem of magic square 
#!/usr/bin/perl -w                                                              
use strict;

#input a number ,judge it is an odd or 4k or 4k+2 or err.
print "Please enter an integer > 2\n";
chomp (my $x = <STDIN>);
my $remain = $x % 4;
my $little = $x/2;
my @a;
if ($x >= 3 )
{
    if (($remain == 1) || ($remain == 3))
    {
        odd($x); #it's an odd.use the subroutin of odd.
    }
    elsif ($remain == 2)
    {
        double_odd($x); #it's 4k+2.use the  subroutin of double_odd.
    }
    elsif ($remain == 0)
    {
        double_even($x); #it's 4k.use the  subroutin of double_even
    }
}
else
{
    print "please enter an integer >2\n";
    exit;
}

#print the magic square 
for(my $i=0;$i<$x;$i++)
{
    for(my $j=0;$j<$x-1;$j++)
    {
        print "$a[$i][$j]\t";
    }
    print "$a[$i][$x-1]\n";#the last element of every row in the array followed"\n".

sub double_odd
{
    my $k=($little-1)/2;
    for(my $i=0;$i<$x;$i++)
    {
        for(my $j=0;$j<$x;$j++)
        {
            $a[$i][$j]=0;
        }
    }
    odd($little);
    for(my $i=0;$i<$little;$i++)
    {
        for(my $j=0;$j<$little;$j++)
        {
            $a[$i][$j+$little]=$a[$i][$j]+50;
            $a[$i+$little][$j]=$a[$i][$j]+75;
            $a[$i+$little][$j+$little]=$a[$i][$j]+25;
        }
    }
    for(my $i=0;$i<$little;$i++)
    {
        if($i!=$k)
        {
            for(my $j=0;$j<$k;$j++)
            {
                my $b = $a[$i][$j];
                $a[$i][$j]=$a[$i+$little][$j];
                $a[$i+$little][$j] = $b;
            }
        }
        else
        {
            for(my $j=$k;$j<2*$k;$j++)
            {
                my $b = $a[$i][$j];
                $a[$i][$j]=$a[$i+$little][$j];
                $a[$i+$little][$j] = $b;
            }
        }
    }
}

sub odd
{
    (my $z) = @_;
    my $i = 0;
    my $j = ($z-1)/2;
    for(my $c=1;$c<=$z * $z;$c++)
    {
        $a[$i][$j] = $c;
        $i--;
        $j++;
        if($a[$i][$j])
        {$i=$i+2;$j--;}
        elsif($i<0 && $j<$z)
        {$i=$z-1;}
        elsif($j>=$z && $i>=0)
        {$j=0;}
        elsif($i<0 && $j>=$z)
        {$i=$i+2;$j--;}
        elsif($i==0 && $j==0)
        {$i=$z-1;}
    }
}

sub double_even
{
    my $n = $x-1;
    my $b = 1;
    for(my $i=0;$i<$x;$i++)

 {
        for(my $j=0;$j<=$n;$j++,$b++)
        {
            $a[$i][$j]=$b;
        }
    }
    for(my $i=0;$i<$x/2;$i++)
    {
        for(my $j=0;$j<$x;$j++)
        {
            if ($i ==$j || $i==($n-$j) || ($i+$j)% 4==3 || ($j-$i)% 4==0)
            {
                my $c=$a[$i][$j];
                $a[$i][$j]=$a[$n-$i][$n-$j];
                $a[$n-$i][$n-$j]=$c;
            }
        }
    }
}