找出长度和宽度严格增加的矩形数

时间:2014-10-14 05:45:24

标签: algorithm data-structures

问题陈述

我已经给出了N个矩形(来自用户的输入),其长度和宽度也被用作用户的输入。

我必须选择具有第一个矩形长度的条件的最大矩形数&gt; <第二矩形的长度和第一矩形的宽度>第二个矩形的宽度。

我的程序

我正在做的是我按照长度和宽度对每个矩形进行排序,然后只考虑长度和宽度递增的矩形,但我的排序不正常。

#include<stdio.h>
#include<stdlib.h>
#define MAX 100
typedef struct 
{
    int length;
    int width;
}Rectangles;

int compare(const void *first,const void *second)
{
    const Rectangles *rect1 = first;
    const Rectangles *rect2 = second;

    if(rect1->length > rect2->length )
    {
        if(rect1->width > rect2->width)
            return 1;
        else if(rect1->width < rect2->width)
            return -1;
        else 
            return -1;
    }

    else if(rect1->length < rect2->length )
    {
        if(rect1->width < rect2->width)
            return -1;
        else if(rect1->width > rect2->width)
            return -1;
        else 
            return -1;
    }
    else
    {
        if(rect1->width < rect2->width)
            return -1;
        else if(rect1->width > rect2->width)
            return -1;
        else 
            return 0;
    }
}

int main()
{
    int i,nRectangleCount;
    Rectangles stRectangle[MAX];
    printf("Enter total number of rectangles\n");
    scanf("%d",&nRectangleCount);
    printf("Enter %d length and width of rectanle\n",nRectangleCount);
    for(i=0;i<nRectangleCount;++i)
    {
        scanf("%d %d",&stRectangle[i].length,&stRectangle[i].width);
    }

    printf("Before Sorting\n");
    for(i=0;i<nRectangleCount;++i)
    {
        printf("%d %d\n", stRectangle[i].length,stRectangle[i].width);  
    }

    qsort(stRectangle,nRectangleCount,sizeof(Rectangles),compare);

    printf("\n\nAfter Sorting\n");
    for(i=0;i<nRectangleCount;++i)
    {
        printf("%d %d\n", stRectangle[i].length,stRectangle[i].width);  
    }
    return 0;
}

我不认为,通过排序解决这个问题是个好主意,我试图计算面积然后根据面积对其进行排序,然后它也不起作用。

还有其他算法可以解决这个问题。?

以下是测试用例:

7
10 12
4 5
15 8
3 18
16 25
1 2
5 10

4 个答案:

答案 0 :(得分:3)

这是一个经典的。通过其中一个坐标(例如,按宽度)对矩形序列进行排序,然后找到其他坐标序列的最长增加子序列(&#34; LIS&#34;)。如果使用动态编程,排序将采用O(nlogn),并找到LIS O(n ^ 2)或O(nlogn)。

关于您的示例,在排序后,您将首先获得序列 (1,2),(3,18),(4,5),(5,10),(10,12),(15,8),(16,25)。

第二坐标序列的最长增加子序列是2,5,10,12,25,最终给出(1,2),(4,5),(5,10),(10,12),( 16,25)。颠倒这个序列会给你一系列符合你条件的矩形。

另见:

答案 1 :(得分:1)

这个问题尖叫动态编程。

考虑一下,如果你只有两个矩形,它会微不足道,对吧?

因此,您使用的核心元素是一个有效(增加,相邻的输入)矩形列表,也包含输入矩形。

基本案例:每个列表都有一个矩形。

归纳/递归步骤:我们可以将后继任务添加到任何当前列表中(即,对于每个矩形列表,查看最后一个矩形,输入中的下一个矩形是否有效添加到该列表中)?

重复感应步骤直到不再添加矩形,然后只扫描列表最长。应用动态编程以降低复杂度(长度为N的数组,由矩形在输入中的位置索引,其值为有效后的元素数量)。

答案 2 :(得分:0)

一个明显的解决方案是:

#include<stdio.h>
#include<stdlib.h>
#define MAX 100
typedef struct 
{
    int length;
    int width;
}Rectangles;

int compare(const void *first,const void *second)
{
    const Rectangles *rect1 = (Rectangles*)first;
    const Rectangles *rect2 = (Rectangles*)second;

    if(rect1->length > rect2->length )
    {
        return 1;
    }
    else if(rect1->length == rect2->length )
    {
        if(rect1->width > rect2->width)
            return 1;
    }
    else
        return -1;
}

int main()
{
    int i,j,nRectangleCount;
    Rectangles stRectangle[MAX];
    int rect_count = 5;
    int count = 0;
    stRectangle[0].length = 5;
    stRectangle[0].width = 12;
    stRectangle[1].length = 8;
    stRectangle[1].width = 10;
    stRectangle[2].length = 14;
    stRectangle[2].width = 9;
    stRectangle[3].length = 11;
    stRectangle[3].width = 16;
    stRectangle[4].length = 4;
    stRectangle[4].width = 6;
    qsort(stRectangle, 5, sizeof(Rectangles), compare);
    for(i=0;i<5;i++) {
        for(j=i+1;j<5;j++)
        {
            if(stRectangle[i].length < stRectangle[j].length && stRectangle[i].width < stRectangle[j].width) {
                printf("%d %d > %d %d\n", stRectangle[i].length,stRectangle[i].width,stRectangle[j].length,stRectangle[j].width);
                count++;
            }
        }
    }
    printf("%d",count);
    return 0;
}

我相信你会找到更好的解决方案。

答案 3 :(得分:0)

我可以想到一个O(n**2)解决方案。为列表中的所有矩形构造有向图,其中每个矩形对应一个顶点。对于每个矩形i,检查所有其他矩形j和

  • if i&gt; j,从i到j
  • 绘制有向边
  • 如果j> i,则从j到i绘制有向边

获得图形后,对于没有入射边缘的每个顶点,找到从该顶点开始的最长路径。然后找到最长路径的总路径。

这是O(n**2)时间和O(n**2)空间。