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

Now in Baidu WISE team

文章分类

全部博文(150)

文章存档

2014年(8)

2013年(31)

2012年(111)

分类: Python/Ruby

2012-04-26 17:21:12

Question:

有一个大方格,将其划分成3*3的9个中方格,将每个中方格划分成3*3的9个小方格(希望我表述明白了),也就是说,现在这个大方格里就有9*9个小方格了,初始的时候,这81个小方格里某一些被随机填上了1-9种任一个数字,另一些则空白,写一个程序,将空白的小方格填上数字(1-9任一数字),要求大方格的每一行跟每一列不得有重复的数字,同时每一个中方格内不得有重复数字.

作为面试题如果要写出来没bug挺不容易。我写的过于啰嗦。

Answer:

要点:

1有点动态规划的意思。每个坐标都会有3种限制。1.行不重复 2列不重复 3块不重复。给定一个部分完成的方格,我们可以推算出指定坐标元素的可选值

2.递归进行。填入一个元素,然后坐标移到下一个。此时待填入的位置所有可能的选择可以根据1的描述给出,然后选一个填入。如此递归进行,每次移动坐标。如果到某位置是可选列表里没有元素,说明之前排列错误,直接放弃。如果到(8,8)点,填完,说明成功,直接退出。


 

点击(此处)折叠或打开

  1. my @pool = (1..9);

  2. #There should be no duplicate element in line
  3. sub RowRestrict{
  4.     my $x = shift;
  5.     my $y = shift;
  6.     my @tm = @_;
  7.     my @tpool;
  8.     for(my $i = 0; $i < $x; $i++){
  9.         push(@tpool, $tm[$y][$i]) if(defined($tm[$y][$i]));
  10.     }
  11.     return @tpool;
  12. }

  13. #there should be no duplicate elemment in column
  14. sub ColumnRestrict{
  15.     my $x = shift;
  16.     my $y = shift;
  17.     my @tm = @_;
  18.     my @tpool;
  19.     for(my $i = 0; $i< $y; $i++){
  20.         push (@tpool, $tm[$i][$x]);
  21.     }
  22.     return @tpool;
  23. }


  24. #there should be no duplicate element in block
  25. sub BlockRestrict{
  26.     my $x = shift;
  27.     my $y = shift;
  28.     my @tm = @_;
  29.     my @tpool;

  30.     my $sx = (int($x/3))*3;
  31.     my $sy = (int($y/3))*3;
  32.     for my $ty ($sy..$sy+2){
  33.         for my $tx ($sx..$sx+2){
  34.             push(@tpool, $tm[$ty][$tx]) if(defined $tm[$ty][$tx]);
  35.         }
  36.     }
  37.     return @tpool;
  38. }

  39. #generate next element position
  40. sub Next{
  41.     my ($x, $y) = @_;
  42.     if($x<8){
  43.         $x++;
  44.     }
  45.     else{
  46.         $x = 0;
  47.         $y ++;
  48.     }
  49.     return $x, $y;
  50. }

  51. #get possible choice of ($x, $y)
  52. sub GetValidNum{
  53.     my ($x, $y, @mtr) = @_;
  54.     my @tpool;
  55.     my @r = (RowRestrict($x,$y,@mtr),ColumnRestrict($x, $y, @mtr), BlockRestrict($x, $y, @mtr));
  56.     for(@pool){
  57.         if($_ ~~ @r){
  58.             next;
  59.         }
  60.         else{
  61.             push(@tpool, $_);
  62.         }
  63.     }
  64.     return @tpool;
  65. }

  66. #output the result
  67. sub Output{
  68.     my @mtr = @_;
  69.     for my $tx (0..8){
  70.         for my $ty (0..8){
  71.             print $mtr[$tx][$ty]."--";
  72.         }
  73.         print "\n";
  74.     }
  75. }

  76. sub f{

  77.     my ($x, $y, @mtr) = @_;
  78.     if($x !=8 or $y != 8){
  79.         ($x, $y) = Next($x, $y);
  80.         
  81.         my @tpool = GetValidNum($x, $y, @mtr);
  82.         if(@tpool == 0){
  83.             return;
  84.         }
  85.         for(@tpool){
  86.             $mtr[$y][$x] = $_;
  87.             f($x, $y, @mtr);
  88.         }
  89.     }
  90.     else{
  91.         print "Find !!\n";
  92.         push(@allresult, \@mtr);
  93.         Output(@mtr);
  94.         #exit when found an anwser, if you want to get all anwser, remove it
  95.         exit;

  96.     }
  97. }

  98. my @metr;
  99. #assign 0 to the (0,0). you can assign another value to it.
  100. $metr[0][0] = 0;
  101. f(0,0,@metr);


 

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