经典分治之棋盘覆盖问题

刘汝佳书上的经典题,不过目前所见过的变式并不多

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<string>
  5 #include<cstdio>
  6 using namespace std;
  7 const int maxn=1500;
  8 int n;
  9 int x,y;
 10 int cnt=0;
 11 int a[maxn][maxn];
 12 int vis[maxn][maxn];
 13 int b[maxn][maxn];
 14 struct temp
 15 {
 16     int x,y;
 17 };
 18 void change(int x)
 19 {
 20     int tot=0;
 21     temp t[5];
 22     for(int i=0;i<n;i++)
 23     for(int j=0;j<n;j++)
 24     {
 25         if(tot==3)
 26             break;
 27         if(a[i][j]==x)
 28         {
 29             tot++;
 30             t[tot].x=i;
 31             t[tot].y=j;
 32         }
 33     }
 34     if(t[1].y==t[3].y&&t[2].x==t[3].x&&t[3].y-t[2].y==1&&t[3].x-t[1].x==1)
 35     {
 36         for(int i=1;i<=3;i++)
 37             b[t[i].x][t[i].y]=1;
 38     }
 39     if(t[1].y==t[2].y&&t[2].x==t[3].x&&t[2].x-t[1].x==1&&t[3].y-t[2].y==1)
 40     {
 41         for(int i=1;i<=3;i++)
 42             b[t[i].x][t[i].y]=2;
 43     }
 44     if(t[1].x==t[2].x&&t[2].y==t[3].y&&t[2].y-t[1].y==1&&t[3].x-t[2].x==1)
 45     {
 46         for(int i=1;i<=3;i++)
 47             b[t[i].x][t[i].y]=3;
 48     }
 49     if(t[1].x==t[2].x&&t[1].y==t[3].y&&t[3].x-t[1].x==1&&t[2].y-t[1].y==1)
 50     {
 51         for(int i=1;i<=3;i++)
 52             b[t[i].x][t[i].y]=4;
 53     }
 54 }
 55 /*
 56 void change(int x,int y)
 57 {
 58     if(vis[x][y])
 59         return;
 60     int tt=a[x][y];
 61     if(a[x][y+1]==tt&&a[x-1][y]==tt)
 62     {
 63         a[x][y]=2;
 64         a[x][y+1]=2;
 65         a[x-1][y]=2;
 66         vis[x][y]=2;
 67         vis[x][y+1]=2;
 68         vis[x-1][y]=2;
 69         return;
 70     }
 71     if(a[x][y+1]==tt&&a[x+1][y]==tt)
 72     {
 73         a[x][y]=4;
 74         a[x][y+1]=4;
 75         a[x+1][y]=4;
 76         vis[x][y]=4;
 77         vis[x][y+1]=4;
 78         vis[x+1][y]=4;
 79         return;
 80     }
 81     if(a[x+1][y]==tt&&a[x][y-1]==tt)
 82     {
 83         a[x][y]=3;
 84         a[x+1][y]=3;
 85         a[x][y-1]=3;
 86         vis[x][y]=3;
 87         vis[x+1][y]=3;
 88         vis[x][y-1]=3;
 89         return;
 90     }
 91     if(a[x][y-1]==tt&&a[x-1][y]==tt)
 92     {
 93         a[x][y]=1;
 94         a[x][y-1]=1;
 95         a[x-1][y]=1;
 96         vis[x][y]=1;
 97         vis[x][y-1]=1;
 98         vis[x-1][y]=1;
 99         return;
100     }
101 }*/
102 void dfs(int x,int y,int x0,int y0,int tmp)
103 {
104     if(tmp==1)
105         return;
106     int t=++cnt;
107     tmp/=2;
108     if(x0<x+tmp&&y0<y+tmp)
109         dfs(x,y,x0,y0,tmp);
110     else
111     {
112         a[x+tmp-1][y+tmp-1]=t;
113         dfs(x,y,x+tmp-1,y+tmp-1,tmp);
114     }
115     if (x0<x+tmp&&y0>=y+tmp)
116         dfs(x,y+tmp,x0,y0,tmp);
117     else
118     {
119         a[x+tmp-1][y+tmp]=t;
120         dfs(x,y+tmp,x+tmp-1,y+tmp,tmp);
121     }
122     if (x0>=x+tmp&&y0<y+tmp)
123         dfs(x+tmp,y,x0,y0,tmp);
124     else
125     {
126         a[x+tmp][y+tmp-1]=t;
127         dfs(x+tmp,y,x+tmp,y+tmp-1,tmp);
128     }
129     if ( x0>=x+tmp&&y0>=y+tmp)
130         dfs(x+tmp,y+tmp,x0,y0,tmp);
131     else
132     {
133         a[x+tmp][y+tmp]=t;
134         dfs(x+tmp,y+tmp,x+tmp,y+tmp,tmp);
135     }
136 }
137 int main()
138 {
139     cin>>n>>x>>y;
140     a[x-1][y-1]=0;
141     dfs(0,0,x-1,y-1,n);
142     for(int i=1;i<=cnt;i++)
143         change(i);
144     b[x-1][y-1]=9;
145     for(int i=0;i<n;i++)
146     {
147         for(int j=0;j<n;j++)
148         {
149             cout<<b[i][j]<<" ";
150         }
151         cout<<endl;
152     }
153     return 0;
154 }

原文地址:https://www.cnblogs.com/aininot260/p/9638049.html

时间: 2024-10-03 14:45:17

经典分治之棋盘覆盖问题的相关文章

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

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

分治算法----棋盘覆盖问题

问题描述 在一个2^k×2^k 个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘.在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖.

棋盘覆盖问题(算法竞赛入门经典)

在一个 2^k * 2^k 个方格组成的棋盘中,若恰有一个方格与其它方格不同,则称该方格为一特殊方格,称该棋盘为一特殊棋盘.显然特殊方格在棋盘上出现的位置有 4^k 种情形.因而对任何 k>=0 ,有 4^k 种不同的特殊棋盘.下图所示的特殊棋盘为 k=2 时 16 个特殊棋盘中的一个. 在棋盘覆盖问题中,要用下图中 4 中不同形态的 L 型骨牌覆盖一个给定的特殊棋牌上除特殊方格以外的所有方格,且任何 2 个 L 型骨牌不得重叠覆盖.易知,在任何一个 2^k * 2^k 的棋盘中,用到的 L 型

【棋盘覆盖】(简单)--分治算法

算法实验1:棋盘覆盖 Time Limit: 1 Sec  Memory Limit: 64 MB Submit: 2798  Solved: 702 [Submit][Status][Discuss] Description 在一个2k x 2k 个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘.在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖. 口            

分治与递归-棋盘覆盖问题

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

棋盘覆盖问题【分治】

棋盘覆盖问题 Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:32768KB Total submit users: 95, Accepted users: 36 Problem 10432 : No special judgement Problem description   在一个2k x 2k ( 即:2^k x 2^k )个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘.

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

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

用分治策略实现棋盘覆盖问题

C++程序源代码如下: // 棋盘覆盖.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include<fstream> using namespace std; int tile=1; //L型骨牌的编号(递增) int board[100][100]; //棋盘 /***************************************************** * 递归

棋盘覆盖问题(递归分治)

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