zoukankan      html  css  js  c++  java
  • BZOJ_2529_[Poi2011]Sticks_贪心

    BZOJ_2529_[Poi2011]Sticks_贪心

    Description

    Little Johnny was given a birthday present by his grandparents. This present is a box of sticks of various lengths and colours. Johnny wonders if there are three sticks in the set he has been given that would form a triangle with different-coloured sides. Let us note that Johnny is interested in non-degenerate triangles only, i.e., those with positive area.

    给出若干木棍,每根木棍有特定的颜色和长度。问能否找到三条颜色不同的木棍构成一个三角形。
    (注意这里所说的三角形面积要严格大于0)

    第一行给出一个整数k(3<=k<=50),表示颜色的种数。这k种颜色被标号为1至k。
    接下来k行,第i+1描述颜色为i的木棍的信息。
    首先一个整数Ni(1<=Ni<=10^6)表示颜色为i的木棍的数量。
    接下来Ni个整数,表示这Ni根木棍各自的长度。
    所有木棍的长度<=10^9。总木棍数量<=10^6。

    你的程序应该仅输出一行
    如果有解,输出6个整数,分别表示第一条边的颜色,第一条边的长度,第二条边的颜色,第二条边的长度,第三条边的颜色,第三条边的长度,这六个整数以空格分割。
    如果有多组解,随便输出一组即可。
    如果无解,输出 NIE

    Sample Input

    4
    1 42
    2 6 9
    3 8 4 8
    1 12

    Sample Output

    3 8 4 12 2 9


    首先按长度排序。

    对于构成三角形有一个很显然的贪心,这三条边的长度要尽可能的接近。

    现在有了颜色的限制,我们处理出nxt[i]表示i的颜色这一段连续的末尾位置。

    然后枚举最短的那条边,中间那条就一定是最短边的下一个颜色的最后一个,因为最短和最长的固定后中间的边显然越长越好。

    然后枚举最长边的颜色,要满足大于等于最短边且长度最小,容易发现这个是单调的。

    总时间复杂度$O(nk)$。能过就行。

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <vector>
    using namespace std;
    #define RR register
    inline char nc() {
        static char buf[100000],*p1,*p2;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int rd() {
        RR int x=0; RR char s=nc();
        while(s<'0'||s>'9') s=nc();
        while(s>='0'&&s<='9') x=(x<<3)+(x<<1)+s-'0',s=nc();
        return x;
    }
    #define N 1000050
    vector<int>v[55];
    int n,K,num[55],nxt[N],pos[55];
    struct A {
        int col,v;
    }a[N];
    bool cmp(const A &x,const A &y) {
        return x.v<y.v;
    }
    int main() {
        K=rd();
        int i,j;
        for(i=1;i<=K;i++) {
            num[i]=rd();
            for(j=1;j<=num[i];j++) {
                a[++n].col=i;
                a[n].v=rd();
            }
        }
        sort(a+1,a+n+1,cmp);
        for(i=1;i<=n;i++) {
            v[a[i].col].push_back(i);
        }
        int now=0;
        for(i=n;i>=1;i--) {
            if(a[i].col!=a[now].col) {
                nxt[i]=i; now=i;
            }else {
                nxt[i]=now;
            }
        }
        int x,y,z;
        for(i=1;i<=n;i++) {
            // printf("col=%d,v=%d,nxt[i]=%d
    ",a[i].col,a[i].v,nxt[i]);
            int x=i,y=nxt[nxt[i]+1];
            if(y==0) continue;
            for(j=1;j<=K;j++) {
                if(j!=a[x].col&&j!=a[y].col&&pos[j]<num[j]) {
                    while(pos[j]<num[j] && a[ v[j][pos[j]] ].v<a[x].v) {
                        pos[j]++;
                    }
                    if(pos[j]>=num[j]) continue;
                    z=v[j][pos[j]];
                    if(a[x].v+a[y].v>a[z].v) {
                        printf("%d %d %d %d %d %d
    ",a[x].col,a[x].v,a[y].col,a[y].v,a[z].col,a[z].v); return 0;
                    }
                }
            }
        }
        puts("NIE");
    }
    
  • 相关阅读:
    合并两个有序列表
    根据前序遍历和中序遍历还原二叉树
    快速排序
    二叉树搜索的后序遍历序列
    最长回文子串
    爬楼梯
    Selenium EC 与 Wait
    爬取Django 绕过csrf实现批量注册
    Django 数据传递 个人汇总贴
    python bytes和str转换
  • 原文地址:https://www.cnblogs.com/suika/p/9062576.html
Copyright © 2011-2022 走看看