经典分治之棋盘覆盖问题

Posted aininot260

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了经典分治之棋盘覆盖问题相关的知识,希望对你有一定的参考价值。

技术分享图片

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

  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 }

 

以上是关于经典分治之棋盘覆盖问题的主要内容,如果未能解决你的问题,请参考以下文章

C++经典算法问题:棋盘覆盖问题(分治算法)!含源码示例

分治算法经典案例 - 棋盘问题

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

棋盘覆盖问题——分治法——代码清晰易懂

《入门经典》——6.24

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