您的位置:首页 > 其它

poj 2886 Who Gets the Most Candies?

2013-07-31 18:04 369 查看
题意:约瑟夫环游戏,第 p个出来的人有F(p)(求p的反素数)个糖果,问糖果最多的人的名字和它有多少个糖果,如果最多的有几个人,输出最先出来的那个人

解题思路:这个题目有很多细节要注意,首先,顺时针的话大的是在他的左边,然后就是要注意它的步数是否是大于人数的,利用线段树的基本性质搜索它的位置就行了

解题代码:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define MAXN 500005
int n, k ;
int a[MAXN];
struct node
{
int left ,right ,mid ;
int num ;
}tree[MAXN * 4];
int L(int c)
{
return 2 * c;
}
int R(int c)
{
return 2 * c + 1;
}
void build(int c, int p , int v)
{
tree[c].left = p ;
tree[c].right = v;
tree[c].mid = (p+v)/2;
tree[c].num = (v-p+1);
if(p == v )
{
return;
}
build(L(c),p,tree[c].mid);
build(R(c),tree[c].mid + 1, v);
}
int tsum = 0  ;
void getsum(int c, int p ,int v )
{
if(p <= tree[c].left && v >= tree[c].right)
{
tsum += tree[c].num;
return;
}
if(v <= tree[c].mid) getsum(L(c),p,v);
else if(p > tree[c].mid ) getsum (R(c),p,v);
else
{
getsum(L(c),p,tree[c].mid);
getsum(R(c),tree[c].mid+1, v );
}
}
int ok =0 ;
void update(int c, int p)
{   tree[c].num -- ;
if(tree[c].left == tree[c].right)
{
ok = tree[c].left;
return;
}
if(tree[L(c)].num >= p ) update(L(c),p);
else update(R(c),p - tree[L(c)].num);
}
char str[MAXN][13];
int RPrime[]={//反素数
1,2,4,6,12,24,36,48,60,120,180,240,360,720,840,
1260,1680,2520,5040,7560,10080,15120,20160,25200,27720,
45360,50400,55440,83160,110880,166320,221760,277200,
332640,498960,554400,665280
};

int fact[]={//反素数约数个数
1,2,3,4,6,8,9,10,12,16,18,20,24,30,32,36,40,48,60,64,72,80,84,
90,96,100,108,120,128,144,160,168,180,192,200,216,224
};

int main()
{

while(scanf("%d %d",&n,&k) != EOF)
{
int P = 0 ;
for(int i= 0; RPrime[i]<= n;i++)P=i;
for(int i = 1;i <= n;i ++)
{
scanf("%s %d",str[i],&a[i]);
}
build(1,1,n);
update(1,k);
int temp = a[k];
int t = 1 ;
int temps = k ;
if(t < RPrime[P])
while(tree[1].num != 0)
{
t ++ ;
if(temp < 0 )
{
tsum = 0 ;
getsum(1,1,temps);
temp = (-temp)%(tree[1].num);
if(temp == 0 )
temp = tree[1].num;
if(tsum >= temp)
{
update(1,tsum-temp + 1);
}
else
{
update(1,tree[1].num - (temp - tsum) + 1 );
}
}
else
{
tsum = 0 ;
getsum(1,temps,n);
temp = temp%(tree[1].num);
if(temp == 0 )
temp = tree[1].num;
if(tsum >= temp)
{
update(1,tree[1].num - (tsum - temp));
}
else
{
update(1,temp - tsum);
}
}
temps = ok;
temp = a[ok];
//    printf("%d\n",ok);

if(t >= RPrime[P])
break;

}
printf("%s %d\n",str[ok],fact[P]);
}
return 0 ;
}


View Code
ps:poj上排名第一的既然是3xian,应该是用图灵树撸过的,无限orz!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: