利用分治法解决棋盘覆盖问题

1.问题描述:点击打开链接

2.代码:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cassert>
#include<string>
#include<sstream>
#include<set>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cctype>
#include<functional>
using namespace std;

#define me(s) memset(s,0,sizeof(s))
#define pb push_back
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair <int, int> P;

const int N = 1 << 11;
int A[N][N];
int n, a, b;
int idx;

void solve(int r1, int r2, int c1, int c2, int x, int y)
{
	if (r2-r1==1)return;
	int t = idx++;
	int mr = (r1 + r2)/2, mc = (c1 + c2)/2;
	if (x<mr&&y<mc)solve(r1, mr, c1, mc, x, y);
	else solve(r1, mr, r2, mc, mr-1,mc-1), A[mr-1][mc-1] = t;

	if (x<mr&&y >= mc)solve(r1, mr, mc, c2, x, y);
	else solve(r1, mr, mc, c2, mr-1,mc), A[mr-1][mc] = t;

	if (x >= mr&&y<mc)solve(mr, r2, c1, mc, x, y);
	else solve(mr, r2, c1, mc, mr,mc-1), A[mr][mc-1] = t;

	if (x >= mr&&y >= mc)solve(mr, r2, mc, c2, x, y);
	else solve(mr, r2, mc, c2, mr,mc), A[mr][mc] = t;
}

int main()
{
	while (~scanf("%d%d%d", &n, &a, &b))
	{
		me(A); idx = 1;
		solve(0, (1 << n), 0, (1 << n), a - 1, b - 1);
		A[a - 1][b - 1] = 0;
		for (int i = 0; i<(1 << n); i++)
		{
			for (int j = 0; j<(1 << n); j++)
			{
				printf("%2d%c", A[i][j], " \n"[j == (1 << n) - 1]);
			}
			puts("");
		}

	}
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-15 11:24:43

利用分治法解决棋盘覆盖问题的相关文章

分治法解决最大子数组问题

利用分治法解决最大子数组问题(对给定的数组得到该数组中具有最大和的子数组) /* * 对于给定的整数数组A,求出数组中具有最大和的子数组,最大和以及左右下标 * 思路:采用分治的方法,将数组分为两部分,则有最大和的子数组共有三种情况 * 在数组左边,在数组右边,跨越数组中点 */ #include <iostream> using namespace std; //存放左右边界值以及sum值的结构体 /*特别注意结构体的使用!!!!!!!!!!!*/ struct SumBorder { in

递归分治解决棋盘覆盖问题

package algorithm; //递归分治解决棋盘覆盖问题 public class ChessBoard { //tr棋盘左上角方格的行号 //tc棋盘左上角方格的列号 //size = 2^k棋盘规格为2^k *2^k //dr特殊方格所在的行号 //dc特殊方格所在的列号 private static int tile = 0;//L型骨牌号 public static int[][] Board = new int[100][100]; public static void ch

用分治法解决最近点对问题:python实现

最近点对问题:给定平面上n个点,找其中的一对点,使得在n个点的所有点对中,该点对的距离最小.需要说明的是理论上最近点对并不止一对,但是无论是寻找全部还是仅寻找其中之一,其原理没有区别,仅需略作改造即可.本文提供的算法仅寻找其中一对. 解决最近点对问题最简单的方法就是穷举法,这样时间复杂度是平方级,可以说是最坏的策略.如果使用分治法,其时间复杂度就是线性对数级,这样大大提高了效率. 首先用分治法解决该问题的基本思路可以参考 http://blog.csdn.net/lishuhuakai/arti

算法题|-分治法解决最大子数组问题

分治法就是将一个复杂难解决问题拆成一些容易解决的小问题,再依次解决而最终解决整个问题 new int[] { 2, -3, 4, 67, 6 } 这样一个下标为0到4的数组,要找最大子数组,需要将其拆分成两个子数组,mid=(0+4)/2 即为0~mid的左数组和mid+1~4的右数组 最大子数组可能会出现在以下三个地方 左数组中的某个最大子数组 右数组中的某个最大子数组 以mid为界,向左找到一个最大数组,向右找到一个最大数组,将两个数组合并 第三种情况非常容易得到,通过遍历查找就可以解决,而

利用分治法求n个数的最大连续和

解决这个问题,采用前缀和平扫的时间复杂度为O(n^2),本文分治法的时间复杂度为O(n*log*(n)) 前缀和平扫首先对n个数做前缀和,接下来利用前缀和枚举每一个区间即可 分治法的代码实现如下: 1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 const int maxn=20000005; 5 const int INF=0x7fffffff; 6 long long a[maxn]; 7

Leetcode 240 Search a 2D Matrix II (二分法和分治法解决有序二维数组查找)

1.问题描述 写一个高效的算法,从一个m×n的整数矩阵中查找出给定的值,矩阵具有如下特点: 每一行从左到右递增. 每一列从上到下递增. 2. 方法与思路 2.1 二分查找法 根据矩阵的特征很容易想到二分法,但是这是一个二维的矩阵,如何将问题转化为一维是关键.实际上我们可以根据矩阵的第一列确定值可能所在的行的范围(limu,limd),其中limu=0,使得matrix[0][0]≤matrix[i][0]≤matrix[limd][0],i∈[0,limd].而确定limd的值可以使用二分法.

分治法解决寻找数组中最大最小值的问题

输入: 数组A[i,…,j] 输出:数组A[i,…,j]中的max和min 1. If  j-i+1 =1   Then 输出A[i],A[i],算法结束 2. If  j-i+1 =2   Then 3.      If  A[i]< A[j]  Then输出A[i],A[j];算法结束 4. k<--(j-i+1)/2 5. m1,M1<--MaxMin(A[i:k]); 6. m2,M2 <--MaxMin(A[k+1:j]); 7. m <--min(m1,m2);

算法复习_分治算法之二分搜索、棋盘覆盖、快速排序

一.基本概念 分治法,顾名思义,即分而治之的算法,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题…… 二.基本思想及策略 设计思想:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之. 策略:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解.这种算法设计策略叫做分治法. 三

棋盘覆盖问题

棋盘覆盖问题       问题描述: 在一个2^k×2^k个方格组成的棋盘中,若有一个方格与其他方格不同,则称该方格为一特殊方格,且称该棋盘为一个特殊棋盘.显然特殊方格在棋盘上出现的位置有4^k种情形.因而对任何k≥0,有4^k种不同的特殊棋盘.     下图–图(1)中的特殊棋盘是当k=3时16个特殊棋盘中的一个: 图(1) 题目要求在棋盘覆盖问题中,要用下图-图(2)所示的4种不同形态的L型骨牌覆盖一个给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖. 图(2) 题目