• 小z的卡片


    小z的卡片
    Time Limit: 1000 MS Memory Limit: 32768 K
    Total Submit: 56(18 users) Total Accepted: 15(12 users) Rating: Special Judge: No
    Description

    小w和小z想到了一个新游戏,在这个游戏中他们各有N个卡片。小w想去使用她的卡片去覆盖小z的卡片。

    卡片A能覆盖卡片B的条件是卡片A的高不小于卡片B的高同时卡片A的宽不小于卡片B的宽。

    现在请计算出小w的牌最多能覆盖小z的牌的数量。注意牌只能被使用一次,并且牌不能被旋转。

     
    Input

    第一行是一个整数t代表测试数据组数。

    对于每组测试数据第一行是一个整数n(n<=100000)代表卡片数量。

    接下来n行每行两个整数h(h<=1000000000)和w(w<=1000000000)代表小w的卡片的高和宽。 

    在接下来n行每行两个整数h(h<=1000000000)和w(w<=1000000000)代表小z的卡片的高和宽。 

     
    Output
    对于每组测试数据,输出小w的牌最多能覆盖小z的牌的数量。
    Sample Input

    2

    2

    1 2

    3 4

    2 3

    4 5

    3

    2 3

    5 7

    6 8

    4 1

    2 5

    3 4 

     
    Sample Output

    1

    2

     

     一开始相出的办法超时了,方法是,对小z的牌排序,然后对于小w的每个牌,找到宽度最接近的,然后覆盖它

    代码:

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<math.h>
    #include<queue>
    using namespace std;
    struct node 
    {
        int height,width;
        int key;
    } a[100001],b[100001];
    bool cmp(node x,node y)
    {
        return x.height<y.height;
    }
    int main()
    {
        int T;
        while(~scanf("%d",&T))
        {
            while(T--)
            {
                int n;
                scanf("%d",&n);
                int i;
                for(i=0;i<n;i++)
                {
                    scanf("%d%d",&a[i].height,&a[i].width);
                }
                for(i=0;i<n;i++)
                {
                    scanf("%d%d",&b[i].height,&b[i].width);
                    b[i].key=0;
                }
                sort(b,b+n,cmp);
                int sum=0,j;
                int width_Max=1000000000;
                int width_Mark;
                for(i=0;i<n;i++)
                {
                    width_Max=1000000000;
                    for(j=0;j<n;j++)
                    {
                        if(b[j].key==1)
                        {
                            continue;
                        }
                        if(b[j].height>a[i].height)
                        {
                            break;
                        }
                        else if(b[j].height<=a[i].height&&b[j].width<=a[i].width)
                        {
                            if(a[i].width-b[j].width<width_Max)
                            {
                                width_Max=a[i].width-b[j].width;
                                width_Mark=j;
                            }
                        }
                    }
                    if(width_Max!=1000000000)
                    {
                        b[width_Mark].key=1;
                        sum++;
                    }
                }
                printf("%d
    ",sum);
            }
        }
        return 0;
    }

    时间复杂度是n*n,这样会超时,

    所以

    把所有卡片放在一起排序,然后把排在前面的小z的卡片装在容器里,遇见小w的卡片,就在容器里找一个最大宽度的可覆盖的卡片

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<math.h>
    #include<queue>
    #include<set>
    using namespace std;
    struct node
    {
        int height,width;
        int key;
    }p[200001];
    bool cmp(node x,node y)
    {
        if(x.height!=y.height)
        {
            return x.height<y.height;
        }
        return x.key>y.key;
    }
    multiset <int> s;
    multiset <int> :: iterator it;
    int main()
    {
        int T;
        while(~scanf("%d",&T))
        {
            while(T--)
            {
                int n;
                scanf("%d",&n);
                int i;;
                for(i=0;i<2*n;i++)
                {
                    scanf("%d%d",&p[i].height,&p[i].width);
                    if(i>=n)
                    {
                        p[i].key=1;
                    }
                    else
                    {
                        p[i].key=0;
                    }
                }
                s.clear();
                sort(p,p+2*n,cmp);
                int sum=0;
                for(i=0;i<2*n;i++)
                {
                    if(p[i].key==1)
                    {
                        s.insert(p[i].width);
                    }
                    else if(!s.empty())
                    {
                        if(*s.begin()<=p[i].width)
                        {
                            it=s.upper_bound(p[i].width);
                            it--;
                            s.erase(it);
                            sum++;
                        }
                    }
                }
                printf("%d
    ",sum);
            }
        }
        return 0;
    }
  • 相关阅读:
    EDM网页邮件代码模板自设计
    Riot.js 框架深入解析
    深入理解 window.onload
    Angular 14 正式 GA
    必须知道的JavaScript库 可视化库
    如何进行EDM邮件制作
    【必须知道的JavaScript库】 解决95%问题的工具插件/库 1
    华为arm主机使用标装版UOS安装时间设置测试
    ubuntu修改date和time
    qtCreator关闭某些编译警告warning的方法(转)
  • 原文地址:https://www.cnblogs.com/beige1315402725/p/5018071.html
Copyright © 2020-2023  润新知