搜索算法
求一个搜索算法
在一个 100 * 100 的格子区域内分布着不规则的可建筑的区域,在这个区域上可以修建 2 * 3, 3 * 2, 4 * 5 等不同长宽的矩形建筑,现在要找出一种浪费的空间最少,且能修建更多大面积建筑的方法。修建更多大面积建筑是指在浪费的空间相同的情况下优先修建 4 * 5 而不是 2 * 3.
输入: 一个 100 * 100 大小的 bool 数组, 为 true 的区域表示可以修建,为 false 的区域为不可修建。
输出:一个包含修建的建筑列表的数组, 建筑的信息包括建筑的位置,宽和高。
我自己写了个算法,效率太低了,当浪费的空间太大时非常慢,消耗的内存也太大,搜索不出来,看看各位高手有什么好的办法?
附我自己的代码:
------解决方案--------------------
------解决方案--------------------
我先说个预处理的思路,如果建筑只包括4*5,2*3,3*2这3个规格,有些情况是根本不可能被覆盖到的,因此可以先将这些小块设为true,
也许会降低一些计算量。
比如(0为空位置):
0000011100
0000001100
0000000111
0000000000
0000000000
右上的4个0是不可能被覆盖的。
[0,5][1,6]这两个点不可能同时被覆盖
[1,6][2,7]这两个点不可能同时被覆盖
这样的情况下,也许可以舍掉[1,6]这个点
------解决方案--------------------
不知道是否可以先计算出一些可以完美覆盖的矩形的尺寸,比如:
2*3 2*6 2*9 ...... 2*99
3*2 3*4 3*6 ...... 3*100
4*3 4*5 4*6 4*8 4*9 4*10 ...... 4* 100
5*6 5*12 5*18......5*96
..........
然后判断可否将空地划分为若干个这个集合里面的矩形。
------解决方案--------------------
写了一个算纯矩形的,没有考虑相同面积下4*5和2*3的问题(如果考虑的话,效率恐怕会下降到n^3)
不知道有了这些数据,对lz后面的程序能否有些帮助
效率大概为(m+k)*n^2
m为建筑的数量,k为建筑最宽的边+建筑最长的边,n为空地的大小
在一个 100 * 100 的格子区域内分布着不规则的可建筑的区域,在这个区域上可以修建 2 * 3, 3 * 2, 4 * 5 等不同长宽的矩形建筑,现在要找出一种浪费的空间最少,且能修建更多大面积建筑的方法。修建更多大面积建筑是指在浪费的空间相同的情况下优先修建 4 * 5 而不是 2 * 3.
输入: 一个 100 * 100 大小的 bool 数组, 为 true 的区域表示可以修建,为 false 的区域为不可修建。
输出:一个包含修建的建筑列表的数组, 建筑的信息包括建筑的位置,宽和高。
我自己写了个算法,效率太低了,当浪费的空间太大时非常慢,消耗的内存也太大,搜索不出来,看看各位高手有什么好的办法?
附我自己的代码:
------解决方案--------------------
------解决方案--------------------
我先说个预处理的思路,如果建筑只包括4*5,2*3,3*2这3个规格,有些情况是根本不可能被覆盖到的,因此可以先将这些小块设为true,
也许会降低一些计算量。
比如(0为空位置):
0000011100
0000001100
0000000111
0000000000
0000000000
右上的4个0是不可能被覆盖的。
[0,5][1,6]这两个点不可能同时被覆盖
[1,6][2,7]这两个点不可能同时被覆盖
这样的情况下,也许可以舍掉[1,6]这个点
------解决方案--------------------
不知道是否可以先计算出一些可以完美覆盖的矩形的尺寸,比如:
2*3 2*6 2*9 ...... 2*99
3*2 3*4 3*6 ...... 3*100
4*3 4*5 4*6 4*8 4*9 4*10 ...... 4* 100
5*6 5*12 5*18......5*96
..........
然后判断可否将空地划分为若干个这个集合里面的矩形。
------解决方案--------------------
写了一个算纯矩形的,没有考虑相同面积下4*5和2*3的问题(如果考虑的话,效率恐怕会下降到n^3)
不知道有了这些数据,对lz后面的程序能否有些帮助
效率大概为(m+k)*n^2
m为建筑的数量,k为建筑最宽的边+建筑最长的边,n为空地的大小
- C# code
private void button2_Click(object sender, EventArgs e) { int[][] buildingSize = new int[][] { new int[] { 2, 3 }, new int[] { 3, 2 }, new int[] { 4, 5 } }; //记录浪费块数的数组 int[,] pRectangle = searchpRect(buildingSize, 100,100); } private int[,] searchpRect(int[][] buildingSize, int width,int height) { //初始化矩阵 int[,] pReturn = new int[width, height]; width++; height++; //初始化矩阵2 int[,] pRectangle = new int[width, height]; for (int i = 0; i < width; i++) for (int j = 0; j < height; j++) pRectangle[i, j] = i * j; //生成可完美覆盖的矩形 int maxWidth = 0; int maxHeight = 0; foreach (int[] bsize in buildingSize) { pRectangle[bsize[0], bsize[1]] = 0; maxWidth = Math.Max(bsize[0], maxWidth); maxHeight = Math.Max(bsize[1], maxHeight); for (int i = bsize[0]; i < width; i++) for (int j = bsize[1]; j < height; j++) if ((pRectangle[i - bsize[0], j] == 0 && pRectangle[bsize[0], j] == 0) || (pRectangle[i, j - bsize[1]] == 0 && pRectangle[i, bsize[1]] == 0)) pRectangle[i, j] = 0; } //生成最少浪费块数 for (int i = 1; i < width; i++) for (int j = 1; j < height; j++) if (pRectangle[i, j] != 0) { pRectangle[i, j] = MinWaste(maxWidth, maxHeight, i, j, pRectangle); pReturn[i - 1, j - 1] = pRectangle[i, j]; } return pReturn; } private int MinWaste(int sWidth,int sHeight, int x, int y, int[,] Rectangle) { int startX = Math.Max(x - sWidth,1); int startY = Math.Max(y - sHeight,1); int min = x * y; for (int i = startX; i < x; i++) min = Math.Min(Rectangle[i, y] + Rectangle[x - i, y],min); for (int i = startY; i < y; i++) min = Math.Min(Rectangle[x, i] + Rectangle[x, y - i], min); return min; }