爱嘉牛LA

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

问题:在2^k*2^k个方格组成的棋盘中,若恰有一个方格与其他方格不同,称该方格为一个特殊方格,且称该棋盘为一特殊棋盘。

思路:

显然特殊在棋盘上出现的位置有4^k中情况。因而对任何K>=0,有4^k中不同的特殊棋盘。

当k>0时,将2k×2k的棋盘分成4个2k-1×2k-1的子棋盘。特殊方格必位于4个较小子棋盘之一中,其余3个子棋盘无特殊方格。为了将这3个无特殊方格的子棋盘转化为特殊棋盘,我们可以用一个L型骨牌覆盖这 3个较小棋盘的汇合处,这3个子棋盘上被L型骨牌覆盖的方格就成为该棋盘上的特殊方格,从而将问题转化为4个较小规模的棋盘覆盖问题。递归地使用这种分割,知道棋盘转化为1×1的棋盘。

计算机算法与分析-21页

View Code
#include <iostream>
using namespace std;
#define N 100
int board[N][N];
int tile=0;
 /*
tr:棋盘左上角方格的行号
tc:棋盘左上角方格的列号
dr:特殊方格所在的行号
dc:特殊方格所在的列号
size:方形棋盘的边长
*/
 void chessboard(int tr,int tc,int dr,int dc,int size)
 {
     int t,s;
     if(size==1) return;
     t=++tile;
     s=size/2;
 
     //特殊方格在左上角
     if(dr<tr+s&&dc<tc+s)
         chessboard(tr,tc,dr,dc,s);
     else
     {
         //此棋盘中无特殊方格 
         //用t号L型骨牌覆盖右下角 
         board[tr+s-1][tc+s-1]=t;
         //覆盖其余方格 
         chessboard(tr,tc,tr+s-1,tc+s-1,s);
     }
 
     //特殊方格在右上角
     if(dr<tr+s&&dc>=tc+s)
         chessboard(tr,tc+s,dr,dc,s);
     else
     {
         board[tr+s-1][tc+s]=t;
         chessboard(tr,tc+s,tr+s-1,tc+s,s);
     }
 
     //特殊方格在左下角
     if(dr>=tr+s&&dc<tc+s)
         chessboard(tr+s,tc,dr,dc,s);
     else
     {
         board[tr+s][tc+s-1]=t;
         chessboard(tr+s,tc,tr+s,tc+s-1,s);
     }
 
     //特殊方格在右下角
     if(dr>=tr+s&&dc>=tc+s)
         chessboard(tr+s,tc+s,dr,dc,s);
     else
     {
         board[tr+s][tc+s]=t;
         chessboard(tr+s,tc+s,tr+s,tc+s,s);
     }
 }
 
 //输出board中的值
 void PrintBoard(int n)
 {
     int i,j;
     for (i=0;i<n;i++)
     {
         for (j=0;j<n;j++)
             printf("%3d",board[i][j]);
         cout<<endl;
     }
 }
int main()
 {
     int tr,tc,dr,dc,size;
     tr=0;
     tc=0;
     cout<<"请输入棋盘的大小(输入的大小必须是能整除4):";
     cin>>size;
     cout<<"请输入特殊方块的行号和列号:";
     cin>>dr>>dc;
     //特殊方格设置为-1号
     board[dr-1][dc-1]=-1;
     chessboard(tr,tc,dr-1,dc-1,size);
     PrintBoard(size);
     return 0;
 }

 

posted on 2012-10-16 18:33  爱嘉牛LA  阅读(272)  评论(0编辑  收藏  举报