zoukankan      html  css  js  c++  java
  • poj 2182

    #include <iostream>
    using namespace std;
    const int maxn=8000+10;
    struct node
    {
    	int l,r,len;
    }tree[maxn*3];
    void Create(int p,int l,int r)
    {
    	tree[p].l=l;
    	tree[p].r=r;
    	tree[p].len=r-l+1;
    	if(l!=r)
    	{
    		int mid=(l+r)/2;
    		Create(2*p+1,l,mid);
    		Create(2*p+2,mid+1,r);
    	}
    }
    int find(int p,int am)
    {
    	tree[p].len--;
    	if(tree[p].l==tree[p].r)
    		return tree[p].l;
    	if(am<=tree[p*2+1].len)
    		return find(p*2+1,am);
    	else
    		return find(p*2+2,am-tree[p*2+1].len);
    }
    int main()
    {
    	int n,a[maxn],b[maxn];
    	while(cin>>n)
    	{
    		int i;
    		Create(0,1,n);
    		for(i=1;i<n;i++)
    			cin>>a[i];
    		for(i=n-1;i>0;i--)
    			b[i]=find(0,a[i]+1);
    		b[0]=find(0,1);
    		for(i=0;i<n;i++)
    			cout<<b[i]<<endl;
    	}
    	return 0;
    }

    暴力的解题思路:在最初的排列中,可以先确定最后位置i的编号:已知a[i],b[i]=a[i]+1,因为他之前的比它小的数已经是除了他之外的所有数。然后在1·n的区间中去掉已得到的数,划区间1-1,1-2,到1-n,得到后的数,在包含它 的区间中删除,对应的区间所包含的数目-1,。然后寻找从后往前的下一个数i每个区间挨着寻找,直到这个区间中1-t所包含的数正好等于a[i]+1,可得b[i]=t,用数组可实现上述算法.

    以此类推,直到剩下最后一个数。再遍历每个区间,知道1~t所包含的数恰好等于1,可得最后剩下的数的编号。时间为O(n2)。

    可以用线段数优化查找区间所用的时间,时间效率可优化到O(nlgn),

  • 相关阅读:
    WPF Video Tutorials
    英语词汇看病
    回车键的含义
    勘误《新概念》IV
    2010年春季C语言程序设计答疑时间地点安排
    勘误《新概念》III
    A potentially dangerous Request.Form value was detected from the client
    推荐WPF的好书(图书)
    *英语词汇交通
    英语词汇房地产
  • 原文地址:https://www.cnblogs.com/lj030/p/3002307.html
Copyright © 2011-2022 走看看