zoukankan      html  css  js  c++  java
  • [BZOJ入门OJ2092][Noip模拟题]舞会

    2092: [Noip模拟题]舞会

    Time Limit: 20 Sec  Memory Limit: 256 MB Submit: 9  Solved: 5 [Submit][Status][Web Board]

    Description

    学校举行舞会啦,一共有N个人参加,所有人站成一排,从左开始编号,最左边的人编号为1 ,最右边的为N。每个人跳舞的熟练度我们用一个整数表示,第i个人的熟练度为Ai,每次熟 练度最接近的一对相邻男女会出列跳舞,如果有多对那么最左边的那一对会先出列,请你给 出出列跳舞的顺序。 输入格式: 第一行一个整数N,第二行N个字符表示N个人的性别,'1'表示男孩,'0'表示女孩。第三行N 个整数表示每人熟练度。

    Input

    第一行一个整数N,第二行N个字符表示N个人的性别,'1'表示男孩,'0'表示女孩。第三行N 个整数表示每人熟练度。 N<=200000.Ai<=10^7.

    Output

    第一行一个整数k,表示一共出列k对人。 下面k行,第i行两个整数ai,bi(ai<bi),表示第i次出列的是编号为ai,bi的一对。

    Sample Input

    4
    1011
    1 1 2 3

    Sample Output

    1
    1 2

    HINT

    Sol

    Source

    并查集+堆

    先把相邻男女加入堆中,形式为三元组$(i,j,val)$,表示编号为$i$和$j$的人,相差为$val$

    这是一个以$val$为关键值的小根堆

    每次不停地弹,直到弹到两人都没跳过

    然后删除这两个人,这两个人删了之后会有两边的人相邻,判断是否为男女,是则加入堆

    至于左右的人用双向链表维护即可,又想骗我写并查集

    #include <queue>
    #include <cstdio>
    using namespace std;
    char buf[10000000], *ptr = buf - 1;
    inline int readint(){
        int f = 1, n = 0;
        char ch = *++ptr;
        while(ch < '0' || ch > '9'){
            if(ch == '-') f = -1;
            ch = *++ptr;
        }
        while(ch <= '9' && ch >= '0'){
            n = (n << 1) + (n << 3) + ch - '0';
            ch = *++ptr;
        }
        return f * n;
    }
    const int maxn = 200000 + 10;
    int N, l[maxn], r[maxn], type[maxn], val[maxn];
    bool out[maxn] = {false};
    struct Node{
        int a, b, v;
        Node(){}
        Node(int _a, int _b, int _v): a(_a), b(_b), v(_v){}
    }t;
    class cmp{
        public:
            bool operator () (const Node &x, const Node &y){
                return x.v == y.v ? x.a > y.a : x.v > y.v;
            }
    };
    inline int abs_(int a){
        return a >= 0 ? a : -a;
    }
    priority_queue<Node, vector<Node>, cmp> q;
    int cnt = 0, ansa[maxn], ansb[maxn];
    int main(){
        fread(buf, sizeof(char), sizeof(buf), stdin);
        N = readint();
        char tmp;
        for(int i = 1; i <= N; i++){
            tmp = *++ptr;
            while(tmp < '0' || tmp > '9') tmp = *++ptr;
            type[i] = tmp - '0';
            l[i] = i - 1;
            r[i] = i + 1;
        }
        for(int i = 1; i <= N; i++)
            val[i] = readint();
        for(int i = 1; i < N; i++)
            if(type[i] != type[i + 1])
                q.push(Node(i, i + 1, abs_(val[i] - val[i + 1])));
        while(!q.empty()){
            t = q.top(); q.pop();
            if(out[t.a] || out[t.b]) continue;
            out[t.a] = out[t.b] = true;
            cnt++;
            ansa[cnt] = t.a;
            ansb[cnt] = t.b;
            int lx = l[t.a], rx = r[t.b];
            r[lx] = rx;
            l[rx] = lx;
            if(lx != 0 && rx != N + 1 && type[lx] != type[rx]) q.push(Node(lx, rx, abs_(val[lx] - val[rx])));
        }
        printf("%d
    ", cnt);
        for(int i = 1; i <= cnt; i++)
            printf("%d %d
    ", ansa[i], ansb[i]);
        return 0;
    }
  • 相关阅读:
    SQL中如何用一个表的列更新另一个表的列?
    ASPxGridView利用CheckBox实现全选
    DevExpress.NETv8.1(Web Controls)学习笔记
    ALSA vs OSS
    video telephone
    uClinux系统分析 转
    Using KVM On Ubuntu 7.10 (Gutsy Gibbon)转
    想买开发板,我真的需要么?
    uClinux的内存管理转
    各种开源软件授权方式的选择 (zt)
  • 原文地址:https://www.cnblogs.com/ruoruoruo/p/7563490.html
Copyright © 2011-2022 走看看