user-0 提问: 求一个不规则图形（其所有角度均为90度）的最大内接矩形的算法

回复:
user: user-1

user: user-2
content: 斜的不能用类似我代码的思路。 仅供参考： 排料问题大牛:http://www2.stetson.edu/~efriedma/packing.html

user: user-2
content: 如果是求最大外接矩形的话……

user: user-0
content: 引用 7 楼 zhao4zhong1 的回复:[/code]   算法明白了，但是这个算法貌似对解决问题帮助不大啊

user: user-2
content: 仅供参考：//实现一个函数：求数轴上多个线段覆盖的区域对应的多个线段; 输入多个线段,求出被这些线段覆盖的所有区域(也用线段表示); 一条线段用两个值表示(x0,x1), 其中x1>x0; //比如(1,3);(2,4);(5,6);结果为(1,4);(5,6); //比如(1,3);(2,4);(5,6);(4,7);结果为(1,7); #include <stdio.h> #define MAXLINES 100 struct LINE {     int x0;//左端     int x1;//右端 } ls[MAXLINES]; int i,j,k,n,x0,x1,c; void add() {     if (0==n) {//加入第一对点         ls[n].x0=x0;         ls[n].x1=x1;         n=1;     } else {         if (x1==ls[0].x0) {//右端＝第一条线段的左端             ls[0].x0=x0;//第一条线段的左端修改为左端             return;         }         if (x1<ls[0].x0) {//右端＜第一条线段的左端             for (i=n-1;i>=0;i--) {//将所有线段往后移                 ls[i+1].x0=ls[i].x0;                 ls[i+1].x1=ls[i].x1;             }             ls[0].x0=x0;//新第一条线段为x0,x1             ls[0].x1=x1;             n++;             return;         }         if (ls[n-1].x1<x0) {//左端＞最后那条线段的右端             ls[n].x0=x0;//新最后那条线段             ls[n].x1=x1;             n++;             return;         }         if (x0<=ls[0].x0 && ls[n-1].x1<=x1) {//左端≤第一条线段的左端且最后那条线段的右端≤右端             ls[0].x0=x0;//只剩这一条线段             ls[0].x1=x1;             n=1;             return;         }         for (i=0;i<n;i++) {//从左到右依次检查每条线段             if (ls[i].x0<=x0 && x0<=ls[i].x1) {//第i条线段的左端≤左端≤第i条线段的右端                 for (j=i;j<n;j++) {//从第i条线段开始从左到右依次检查每条线段                     if (ls[j].x0<=x1 && x1<=ls[j].x1) {//第j条线段的左端≤右端≤第j条线段的右端                         ls[i].x1=ls[j].x1;//第i条线段的右端改为第j条线段的右端                         for (k=1;k<=n-j-1;k++) {//将剩余线段往前移                             ls[i+k].x0=ls[j+k].x0;                             ls[i+k].x1=ls[j+k].x1;                         }                         n-=j-i;                         return;                     }                     if (ls[j].x1<x1 && (j==n-1 || x1<ls[j+1].x0)) {//第j条线段的右端＜右端＜第j+1条线段的左端(如果有)                         ls[i].x1=x1;//第i条线段的右端改为右端                         for (k=1;k<=n-j-1;k++) {//将剩余线段往前移                             ls[i+k].x0=ls[j+k].x0;                             ls[i+k].x1=ls[j+k].x1;                         }                         n-=j-i;                         return;                     }                 }             }             if (ls[i].x1<x0 && (i==n-1 || x0<ls[i+1].x0)) {//第i条线段的右端＜左端＜第i+1条线段的左端(如果有)                 if (i!=n-1 && x1<ls[i+1].x0) {//右端＜第i+1条线段的左端(如果有)                     for (k=n-1;k>=i+1;k--) {//将从第i+1条线段开始的所有线段往后移                         ls[k+1].x0=ls[k].x0;                         ls[k+1].x1=ls[k].x1;                     }                     ls[i+1].x0=x0;//新第i+1条线段为x0,x1                     ls[i+1].x1=x1;                     n++;                     return;                 }                 for (j=i+1;j<n;j++) {//从第i+1条线段开始从左到右依次检查每条线段                     if (ls[j].x0<=x1 && x1<=ls[j].x1) {//第j条线段的左端≤右端≤第j条线段的右端                         ls[i+1].x0=x0;//第i+1条线段的左端改为左端                         ls[i+1].x1=ls[j].x1;//第i+1条线段的右端改为第j条线段的右端                         for (k=1;k<=n-j-1;k++) {//将剩余线段往前移                             ls[i+1+k].x0=ls[j+k].x0;                             ls[i+1+k].x1=ls[j+k].x1;                         }                         n-=j-i-1;                         return;                     }                     if (ls[j].x1<x1 && (j==n-1 || x1<ls[j+1].x0)) {//第j条线段的右端＜右端＜第j+1条线段的左端(如果有)                         ls[i+1].x0=x0;//第i+1条线段的左端改为左端                         ls[i+1].x1=x1;//第i+1条线段的右端改为右端                         for (k=1;k<n-j-1;k++) {//将剩余线段往前移                             ls[i+k].x0=ls[j+k].x0;                             ls[i+k].x1=ls[j+k].x1;                         }                         n-=j-i-1;                         return;                     }                 }             }             if (x0<ls[i].x0) {//左端＜第i条线段的左端                 for (j=i;j<n;j++) {//从第i条线段开始从左到右依次检查每条线段                     if (ls[j].x0<=x1 && x1<=ls[j].x1) {//第j条线段的左端≤右端≤第j条线段的右端                         ls[i].x0=x0;//第i条线段的左端改为左端                         ls[i].x1=ls[j].x1;//第i条线段的右端改为第j条线段的右端                         for (k=1;k<=n-j-1;k++) {//将剩余线段往前移                             ls[i+k].x0=ls[j+k].x0;                             ls[i+k].x1=ls[j+k].x1;                         }                         n-=j-i;                         return;                     }                     if (ls[j].x1<x1 && (j==n-1 || x1<ls[j+1].x0)) {//第j条线段的右端＜右端＜第j+1条线段的左端(如果有)                         ls[i].x0=x0;//第i条线段的左端改为左端                         ls[i].x1=x1;//第i条线段的右端改为右端                         for (k=1;k<=n-j-1;k++) {//将剩余线段往前移                             ls[i+k].x0=ls[j+k].x0;                             ls[i+k].x1=ls[j+k].x1;                         }                         n-=j-i;                         return;                     }                 }             }         }     } } void show() {     for (i=0;i<n;i++) {         printf("(%d,%d);",ls[i].x0,ls[i].x1);     }     printf("\n"); } void main() {     n=0;     c=0;     while (1) {         printf("Input x0,x1(x0<x1;0,0 to exit):");         fflush(stdout);         rewind(stdin);         if (2==scanf("%d,%d",&x0,&x1)) {             if (0==x0&&0==x1) break;             if (x1>x0) {                 c++;                 if (c>=MAXLINES) {                     printf("Up to %d!\n",MAXLINES);                     break;                 }                 add();                 show();             }         }     } }

user: user-3
content: 最大矩形可能是斜的

user: user-4
content: 引用 3 楼 weixin_39014139 的回复:[quote=引用 1 楼 user-4 的回复:] 时间复杂度不超过n2有点难啊， 不然把每个边界点（角的顶点）的最大矩形都算出来，然后比较就行了  把各个顶点求出来之后，怎么继续求每个角的最大矩形啊，求教[/quote]  看你的画的图的图形还是很规则的，就只要上下左右四个方向找最大矩形就行了； 如果是很不规则的图形，那就找出这个点出发不超出矩形的最长的两条垂直线

user: user-0
content: 引用 1 楼 user-4 的回复:时间复杂度不超过n2有点难啊， 不然把每个边界点（角的顶点）的最大矩形都算出来，然后比较就行了  把各个顶点求出来之后，怎么继续求每个角的最大矩形啊，求教

user: user-3
content: baidu扫描线算法

user: user-4
content: 时间复杂度不超过n2有点难啊， 不然把每个边界点（角的顶点）的最大矩形都算出来，然后比较就行了