POJ2182(排队问题)

Lost Cows

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 10695   Accepted: 6865


Description

N (2 <= N <= 8,000) cows have unique brands in the range 1..N. In a spectacular display of poor judgment, they visited the neighborhood ‘watering hole‘ and drank a few too many beers before dinner. When it was time to line up for their evening meal, they did not line up in the required ascending numerical order of their brands.

Regrettably, FJ does not have a way to sort them. Furthermore, he‘s not very good at observing problems. Instead of writing down each cow‘s brand, he determined a rather silly statistic: For each cow in line, he knows the number of cows that precede that cow in line that do, in fact, have smaller brands than that cow.

Given this data, tell FJ the exact ordering of the cows.

Input

* Line 1: A single integer, N

* Lines 2..N: These N-1 lines describe the number of cows that precede a given cow in line and have brands smaller than that cow. Of course, no cows precede the first cow in line, so she is not listed. Line 2 of the input describes the number of preceding cows whose brands are smaller than the cow in slot #2; line 3 describes the number of preceding cows whose brands are smaller than the cow in slot #3; and so on.

Output

* Lines 1..N: Each of the N lines of output tells the brand of a cow in line. Line #1 of the output tells the brand of the first cow in line; line 2 tells the brand of the second cow; and so on.

Sample Input

5
1
2
1
0

Sample Output

2
4
5
3
1题意:第一行给出cow的数目n,接下来2-n行给出每个排在第2-n各位置的cow的在其编号比其小的个数。最后按排队顺序依次给出每个cow的编号。思路:从后向前确定编号,设比最后一个cow小的cow数目为a,则最后一个cow的编号为所剩下cow 的第(a+1)大编号。
#include"cstdio"
#include"cstring"
#include"algorithm"
using namespace std;
const int MAXN=8005;
int n;
int deg[MAXN];
int vis[MAXN];
int ans[MAXN];
int seek(int k)
{
    int pos=0;
    for(int i=1;i<=n;i++)
    {
        if(!vis[i])
        {
            pos++;
            if(pos==k)    return i;
        }
    }
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        memset(vis,0,sizeof(vis));
        deg[0]=0;
        for(int i=1;i<n;i++)
        {
            scanf("%d",&deg[i]);
        }
        for(int i=n-1;i>=0;i--)
        {
            int pos=seek(deg[i]+1);
            vis[pos]=1;
            ans[i]=pos;
        }
        for(int i=0;i<n;i++)
        {
            printf("%d\n",ans[i]);
        }

    }

    return 0;
}

转化为排队问题,利用线段树求解.

#include"cstdio"
#include"cstring"
#include"algorithm"
using namespace std;
const int MAXN=8005;
struct node{
    int l,r;
    int n;
}a[MAXN*4];
int que[MAXN];
int pos[MAXN];
void build(int rt,int l,int r)
{
    a[rt].l=l;
    a[rt].r=r;
    a[rt].n=(r-l+1);
    if(l==r)    return;
    int mid=(l+r)>>1;
    build(rt<<1,l,mid);
    build((rt<<1)|1,mid+1,r);
}

void update(int rt,int pos,int i)
{
    if(a[rt].l==a[rt].r)
    {
        a[rt].n--;
        que[i]=a[rt].l;
        return ;
    }

    if(pos<=a[rt<<1].n)    update(rt<<1,pos,i);
    else update((rt<<1)|1,pos-a[rt<<1].n,i);
    a[rt].n=a[rt<<1].n+a[(rt<<1)|1].n;
}

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        build(1,1,n);
        pos[0]=0;
        for(int i=1;i<n;i++)
        {
            scanf("%d",&pos[i]);
        }
        for(int i=n-1;i>=0;i--)
        {
            update(1,pos[i]+1,i);
        }
        for(int i=0;i<n;i++)
        {
            printf("%d\n",que[i]);
        }
    }

    return 0;
}
时间: 2024-11-11 11:33:54

POJ2182(排队问题)的相关文章

HDU5592 排队问题 xingxing在努力

题意就不多说了, 题可以转化为排队问题, 我们可以使用树状数组来维护,代码如下: #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int maxn = 50010; int n; int c[maxn]; int lowbit(int x) { return x&(-x); } int sum(int i) { int s = 0; whil

POJ 2827 Buy Tickets(排队问题,线段树应用)

POJ 2827 Buy Tickets(排队问题,线段树应用) ACM 题目地址:POJ 2827 Buy Tickets 题意: 排队买票时候插队. 给出一些数对,分别代表某个人的想要插入的位置Pos_i和他的Val_i,求出最后的队列的val顺序. 分析: 也是一道很巧妙的题目. 刚开始天真的以为sort一下就行了.wa了一发后发现我错了... 原来可以很巧妙的用线段树做.由于某个人想要插入posi位置,插入后他就在posi位置上了,但是可能其他人会插到他前面来,他的位置就会变成[在他后面

Codevs 2956 排队问题

2956 排队问题 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 黄金 Gold 题目描述 Description 有N个学生去食堂,可教官规定:必须2人或3人组成一组,求有多少种不同分组的方法. 输入描述 Input Description 一个数,N 输出描述 Output Description 一个数,即答案. 样例输入 Sample Input 6 样例输出 Sample Output 2 数据范围及提示 Data Size & Hint N<=150 50分TL

codevs——2956 排队问题

2956 排队问题 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 有N个学生去食堂,可教官规定:必须2人或3人组成一组,求有多少种不同分组的方法. 输入描述 Input Description 一个数,N 输出描述 Output Description 一个数,即答案. 样例输入 Sample Input 6 样例输出 Sample Output 2 数据范围及提示 Data Size & Hint N<=150 递推

POJ 2828 Buy Tickets(排队问题,线段树应用)

POJ 2828 Buy Tickets(排队问题,线段树应用) ACM 题目地址:POJ 2828 Buy Tickets 题意: 排队买票时候插队. 给出一些数对,分别代表某个人的想要插入的位置Pos_i和他的Val_i,求出最后的队列的val顺序. 分析: 也是一道非常巧妙的题目. 刚開始天真的以为sort一下即可了.wa了一发后发现我错了... 原来能够非常巧妙的用线段树做.因为某个人想要插入posi位置,插入后他就在posi位置上了,可是可能其它人会插到他前面来,他的位置就会变成[在他

POJ2182 Lost Cows 树状数组

一群牛,编号为1到n,但是编号乱了,已知每只牛的前面有多少只编号比其小,求出牛的编号. 插点问段. 这道题要从后面反推回来,比如最后的一只牛,知道有a只编号比它小,则它的编号为a+1. update  更新已经确定的编号, sum(i)   查询已经确定的编号中(后面的牛的编号都确定了),有多少个比i小. 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 const int MAXN=8000+

POJ2182题解——线段树

POJ2182题解——线段树 2019-12-20 by juruoOIer 1.线段树简介(来源:百度百科) 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度为O(logN).而未优化的空间复杂度为2N,实际应用时一般还要开4N的数组以免越界,因此有时需要离散化让空间压缩. 2.线段树实际应用 上面的都是些基本的线段树结构,但只有这些并不能做什么,就好比一个程序有

高矮不同的人排队问题

12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种? (Java版) 思路: 从网上看了半天人家的分析,终于看明白了,在这里记录一下自己的思路 先用一组数来代表这12个人, 1,2,3,4,5,6 7,8,9,10,11,12  排成两排,每排要递增排列,且对应位置第二排要大于第一排,则可以是 1 2 3  4  5    6       =>   第一排的数用0来表示,第二排的数用1来表示,则这个数组序列就是 000000 111111 7

排队问题

[题目描述] 有N个学生去食堂,可教官规定:必须2人或3人组成一组,求有多少种不同分组的方法. [输入描述] 一个数,N. [输出描述] 一个数,即答案. [样例输入] 6 [样例输出] 2 [数据范围及提示] N <= 150. 递推DP: 源代码: #include<cstdio> int n; long long f[151]; int main() { scanf("%d",&n); f[2]=f[3]=1; for (int a=4;a<=n;