poj 2182
来源:互联网 发布:人工智能有哪些领域 编辑:程序博客网 时间:2024/05/21 08:38
题目意思很忽悠人,其实和poj 2828一模一样。就是对于一个序列,其数值为前面比它小的数值个数,最后输出在此下标下每个值所对应的真是排名(很拗口,最好看看poj 2828,意思是一样的)
这道题的解法很简单。对于给定序列从前往后扫描,对于每个数值a[i],每次顺序地把a[i]+1个元素删去(用个数组vis记录情况),则其实际排名则是最后循环j所停留的位置。
可能说得很笼统,就先看一下这个O(n*n)的代码吧,看了就明白了:
- #include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int M=8005;
int a[M],c[M];
int p[M];
bool vis[M];
int n; - int main()
{
scanf("%d",&n);
int i,j;
for(i=2;i<=n;i++)
scanf("%d",&a[i]);
a[1]=0;
- for(i=n;i>0;i--)
{
int cnt=0;
for(j=1;j<=n;j++)
if(!vis[j])
{
cnt++;
if(cnt==a[i]+1)
break;
}
p[i]=j;
vis[j]=1;
}
- for(i=1;i<=n;i++)
printf("%d/n",p[i]);
return 0;
}
对于静态的数据统计问题,树状数组是个很不错的工具,这里树状数组的下标才是真正的排名,原理就是O(n*n)那个算法的思想,只是查询效率大大提高。
以下是代码:
- #include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int M=9000;
int c[M];
int a[M],p[M];
int n; - int lowbit(int n)
{
return n&(-n);
} - int getsum(int n)
{
int ans=0;
while(n>0)
{
ans+=c[n];
n-=lowbit(n);
}
return ans;
} - void update(int n,int num)
{
while(n<M)
{
c[n]+=num;
n+=lowbit(n);
}
} - int binsearch(int x)
{
int low=1,high=n;
while(low<=high)
{
int mid=(low+high)>>1;
int temp=getsum(mid);
if(temp==x)
return mid;
else
{
if(x<temp)
high=mid-1;
else
low=mid+1;
}
}
return 0;
} - int main()
{
int i;
memset(c,0,sizeof(c));
scanf("%d",&n);
a[1]=0;
update(1,1);
for(i=2;i<=n;i++)
{
scanf("%d",&a[i]);
update(i,1);
}
for(i=n;i>0;i--)
{
int s=binsearch(a[i]);
s++;
while(getsum(s)!=a[i]+1)
s++;
a[i]=s;
update(s,-1);
}
for(i=1;i<=n;i++)
printf("%d/n",a[i]);
return 0;
}
线段树同样也可以做出来,思想还是不变,这也许是算法美丽的地方吧,它的外在表现可以千变万化而思想实质则是永恒:
- #include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int M=8010;
struct Tree
{
int l,r;
int cnt;
}T[3*M];
int a[M],ans[M];
int n,N; - void build(int l,int r,int p)
{
T[p].l=l;
T[p].r=r;
T[p].cnt=r+1-l;
if(l==r) return ;
int mid=(l+r)>>1;
build(l,mid,p<<1);
build(mid+1,r,p<<1|1);
} - void del(int x,int p)
{
if(T[p].l==T[p].r)
{
ans[n]=T[p].l;
T[p].cnt=0;
return ;
}
if(x<=T[p<<1].cnt)
del(x,p<<1);
else
del(x-T[p<<1].cnt,p<<1|1);
T[p].cnt--;
} - int main()
{
scanf("%d",&N);
int i;
a[1]=0;
for(i=2;i<=N;i++)
scanf("%d",&a[i]);
build(1,N,1);
for(n=N;n>0;n--)
{
del(a[n]+1,1);
}
for(i=1;i<=N;i++)
printf("%d/n",ans[i]);
return 0;
}
- POJ 2182
- poj 2182
- poj 2182
- poj 2182
- poj 2182
- poj 2182
- poj 2182
- poj 2182
- poj 2182
- poj 2182
- poj 2182
- poj 2182
- poj 2182
- POJ 2182 :Lost Cows
- poj 2182 Lost Cows
- poj 2182 Lost Cows
- poj 2182 Lost Cows
- POJ 2182 Lost Cows
- os toy
- 菜鸟篇:Windows下配置 Apache PHP Mysql 的开发环境
- Oracle10g RAC Oracle Linux 上安装
- haskell的类型转换
- CSS 对浏览器的兼容性技巧总结
- poj 2182
- QTP模拟鼠标和键盘事件整理
- 转自淘宝中间件 架构吧...挺好~~
- suse linux 配置双线ip | suse linux 配置单网卡双ip
- trigger
- quotation
- quotation2 dynamic
- VB keybd_event函数怎么用
- 【转】windows xp下安装pear