分治——棋盘覆盖
2017-06-08 10:58
274 查看
http://prayer.hustoj.com/problem.php?id=1350
题目描述
在一个2^k * 2^k个方格组成的棋盘中,若恰有一个方格与其它方格不同,则称该方格为一特殊方格,称改棋盘为一特殊棋盘。显然特殊方格在棋盘上出现的位置有4^k种情形。因而对任何k>=0,有4^k种不同的特殊棋盘。下图所示的特殊棋盘为k=2时16个特殊棋盘中的一个。
在棋盘覆盖问题中,要用下图中4中不同形态的L型骨牌覆盖一个给定的特殊棋牌上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。易知,在任何一个2^k * 2^k的棋盘中,用到的L型骨牌个数恰为(4^k-1)/3。
输入
输入正方形的变成n,n一定是2的整数次幂,另外还有两个数是特殊方格的位置
输出
输出摆放的方案,特殊方格用0表示,两个整数之间用一个空格隔开,行末没有空格。
注意,要按照从上到下,从左到右的顺序依次给他们编号,具体见样例
样例输入
4 1 1
样例输出
0 1 2 2
1 1 3 2
4 3 3 5
4 4 5 5
提示
n小于100
很经典的例题对不对;
其实我们递归分治就好了;
对于一个正方形,里面有一个点空缺;
那么我们把正方形一半一半,分成4份;
其中有一份就是有个空缺的;
那我们把另外三份的交接点上放一个L型的块;
这样的话洗个小正方形都有一个空缺,直接递归
有人写的代码竟然比我短,我靠
题目描述
在一个2^k * 2^k个方格组成的棋盘中,若恰有一个方格与其它方格不同,则称该方格为一特殊方格,称改棋盘为一特殊棋盘。显然特殊方格在棋盘上出现的位置有4^k种情形。因而对任何k>=0,有4^k种不同的特殊棋盘。下图所示的特殊棋盘为k=2时16个特殊棋盘中的一个。
在棋盘覆盖问题中,要用下图中4中不同形态的L型骨牌覆盖一个给定的特殊棋牌上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。易知,在任何一个2^k * 2^k的棋盘中,用到的L型骨牌个数恰为(4^k-1)/3。
输入
输入正方形的变成n,n一定是2的整数次幂,另外还有两个数是特殊方格的位置
输出
输出摆放的方案,特殊方格用0表示,两个整数之间用一个空格隔开,行末没有空格。
注意,要按照从上到下,从左到右的顺序依次给他们编号,具体见样例
样例输入
4 1 1
样例输出
0 1 2 2
1 1 3 2
4 3 3 5
4 4 5 5
提示
n小于100
很经典的例题对不对;
其实我们递归分治就好了;
对于一个正方形,里面有一个点空缺;
那么我们把正方形一半一半,分成4份;
其中有一份就是有个空缺的;
那我们把另外三份的交接点上放一个L型的块;
这样的话洗个小正方形都有一个空缺,直接递归
#include<bits/stdc++.h> #define Ll long long using namespace std; const int N=1e2+5; int a ,ll; int n,x,y; void dfs(int x,int xx,int y,int yy,int X,int Y,int Z){ if(x==xx&&y==yy)return; int mx=(x+xx)/2; int my=(y+yy)/2; a[mx][my]=a[mx+1][my]=a[mx][my+1]=a[mx+1][my+1]=++ll; int k=0; if(X<=mx&&Y<=my)a[mx ][my ]=0,a[X][Y]=Z,k=1,dfs(x ,mx ,y ,my ,X,Y,Z); if(X<=mx&&Y>my )a[mx ][my 4000 +1]=0,a[X][Y]=Z,k=2,dfs(x ,mx ,my+1,yy,X,Y,Z); if(X> mx&&Y<=my)a[mx+1][my ]=0,a[X][Y]=Z,k=3,dfs(mx+1,xx,y ,my ,X,Y,Z); if(X> mx&&Y> my)a[mx+1][my+1]=0,a[X][Y]=Z,k=4,dfs(mx+1,xx,my+1,yy,X,Y,Z); if(k!=1)dfs(x ,mx ,y ,my ,mx ,my ,a[mx ][my ]); if(k!=2)dfs(x ,mx ,my+1,yy,mx ,my+1,a[mx ][my+1]); if(k!=3)dfs(mx+1,xx,y ,my ,mx+1,my ,a[mx+1][my ]); if(k!=4)dfs(mx+1,xx,my+1,yy,mx+1,my+1,a[mx+1][my+1]); } void DFS(int i,int j,int z){ int v=a[i][j]; a[i][j]=z; if(a[i][j-1]==v)DFS(i,j-1,z); if(a[i][j+1]==v)DFS(i,j+1,z); if(a[i-1][j]==v)DFS(i-1,j,z); if(a[i+1][j]==v)DFS(i+1,j,z); } int main() { scanf("%d%d%d",&n,&x,&y); dfs(1,n,1,n,x,y,0); x=ll; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(a[i][j]&&a[i][j]<=x)DFS(i,j,++ll); if(a[i][j])a[i][j]-=x; printf("%d ",a[i][j]); }printf("\n"); } }
有人写的代码竟然比我短,我靠
相关文章推荐
- 棋盘覆盖问题(递归分治)
- 棋盘覆盖(分治加递归)
- 棋盘覆盖--分治法
- 棋盘覆盖问题(分治)
- 分治与递归-棋盘覆盖问题
- 分治-棋盘覆盖
- 分治:棋盘覆盖的java程序实现
- 棋盘覆盖问题 - 分治法
- 棋盘覆盖问题【分治】
- 棋盘覆盖-分治
- 算法篇-2-分治思想-棋盘覆盖&归并排序&Strasssen矩阵乘法&循环赛安排
- 高效算法设计_递归与分治(棋盘覆盖问题,循环日程表,巨人与鬼)
- 分治---二分搜索,棋盘覆盖
- 棋盘覆盖(分治、递归)
- 棋盘覆盖问题(递归与分治)
- 棋盘覆盖问题(递归与分治,紫书P229)
- 棋盘覆盖(分治典例)
- 棋盘覆盖->分治-分而治之
- 棋盘覆盖问题【分治】
- 实验一 分治与递归―棋盘覆盖问题 java实现