棋盘覆盖

#include<iostream>
#include<fstream>
#include<queue>
#include<cstdlib>
#include<windows.h>
using namespace std;

#define _DEBUG

#ifdef _DEBUG
ifstream fin("C:\\data5.in");
ofstream fout("C:\\data5.out");
#endif

struct position{
       position(int posx=0,int posy=0):x(posx),y(posy){}
       position& operator=(const position& ps){x=ps.x;y=ps.y;return *this;}
       int x;
       int y;
};

const int MAXNUM=32767;
int chessboard[100][100];
int boarderLength;
int cnt=0;
int order=0;
queue<position> CenterNode;
int transMatrix[4][2]={{-1,-1},{-1,1},{1,-1},{1,1}};

void print();
int power(int n)
{
    int ans=1;
    for(int i=0;i<n;++i)
    ans*=2;
    return ans;
}

int exponent(int x)
{
    x=x*3+1;
    int exp=0;
    while(x!=0)
    {
          ++exp;
          x/=4;
    }
    return exp-1;
}

bool hasBlackDot(int xLeftTop,int yLeftTop,int xRightBottom,int yRightBottom)
{
     bool hasBlack=false;
     for(int x=xLeftTop+1;x<=xRightBottom;++x)
     {
           for(int y=yLeftTop+1;y<=yRightBottom;++y)
           {
                 if(chessboard[x][y]!=0)
                 {
                       hasBlack=true;
                       break;
                 }
           }
     }
     return hasBlack;
}

void TurnToBlack(position pos,int length)
{
     ++cnt;
     if(!hasBlackDot(pos.x-length,pos.y-length,pos.x,pos.y))
           chessboard[pos.x][pos.y]=cnt;
     if(!hasBlackDot(pos.x,pos.y-length,pos.x+length,pos.y))
           chessboard[pos.x+1][pos.y]=cnt;
     if(!hasBlackDot(pos.x-length,pos.y,pos.x,pos.y+length))
           chessboard[pos.x][pos.y+1]=cnt;
     if(!hasBlackDot(pos.x,pos.y,pos.x+length,pos.y+length))
           chessboard[pos.x+1][pos.y+1]=cnt;
     print();
     Sleep(1000);
}

void PushIntoQueue(int x,int y)
{
     position pos(x,y);
     CenterNode.push(pos);
}

void BFS()
{
     while(!CenterNode.empty())
     {
           position pos=CenterNode.front();
           //下面一行可以化简 
           int length=boarderLength/(power(exponent(cnt-1))+1);
           if(length==0)
           break;
           //涂黑 
           TurnToBlack(pos,length);
           length/=2;
           for(int i=0;i<4;++i)
                 PushIntoQueue(pos.x+length*transMatrix[i][0],pos.y+length*transMatrix[i][1]);
           CenterNode.pop();
     }
}     

void Init()
{
     int k;
     fin>>k;
     boarderLength=power(k);
     for(int i=1;i<=boarderLength;++i)
     for(int j=1;j<=boarderLength;++j)
     chessboard[i][j]=0;
     int blackposx,blackposy;
     fin>>blackposx>>blackposy;
     chessboard[blackposx][blackposy]=++cnt;
     PushIntoQueue(boarderLength/2,boarderLength/2);
     print();
     Sleep(1000);
     BFS();
}

void print()
{
     cout<<"第"<<++order<<"次:"<<endl; 
     for(int i=1;i<=boarderLength;++i)
     {
             for(int j=1;j<=boarderLength;++j)
             {
                     if(chessboard[i][j]!=0)
                     cout<<chessboard[i][j]<<"\t";
                     else
                     cout<<"□\t";
             }
             cout<<endl;
     }
     cout<<endl;
}

int main()
{
    Init();
    system("pause");
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值