您的位置:首页 > 其它

poj 2886 Who Gets the Most Candies?

2016-11-27 15:10 1121 查看
Who Gets the Most Candies?
Time Limit: 5000MS Memory Limit: 131072K
Total Submissions: 13941 Accepted: 4410
Case Time Limit: 2000MS
Description

N children are sitting in a circle to play a game.

The children are numbered from 1 to N in clockwise order. Each of them has a card with a non-zero integer on it in his/her hand. The game starts from the K-th child, who tells all the others the integer on his card and jumps out of the
circle. The integer on his card tells the next child to jump out. Let A denote the integer. If A is positive, the next child will be the A-th child to the left. If A is negative, the next child will be the (−A)-th
child to the right.

The game lasts until all children have jumped out of the circle. During the game, the p-th child jumping out will get F(p) candies where F(p) is the number of positive integers that perfectly divide p.
Who gets the most candies?

Input

There are several test cases in the input. Each test case starts with two integers N (0 < N ≤ 500,000) and K (1 ≤ K ≤ N) on the first line. The next N lines contains the names of the children
(consisting of at most 10 letters) and the integers (non-zero with magnitudes within 108) on their cards in increasing order of the children’s numbers, a name and an integer separated by a single space in a line with no leading or trailing
spaces.
Output

Output one line for each test case containing the name of the luckiest child and the number of candies he/she gets. If ties occur, always choose the child who jumps out of the circle first.

Sample Input
4 2
Tom 2
Jack 4
Mary -1
Sam 1

Sample Output
Sam 3

Source

POJ Monthly--2006.07.30, Sempr


提示

题意:

有n个小盆友围成一圈玩游戏。

我们以顺时针方向为每个小盆友标从1-n号(0<n<=500000),游戏规则是给每个人一张卡,卡上写有一个整数。游戏从第k个小盆友开始且这位小盆友出圈,若手上的是正数p,则向右数(顺时针)p个人,若是负数,则向左数(逆时针)p个人。直至全部人出圈,第i个人出圈将会得到 i 的因子个数的糖果数,求出得到最多糖果数小盆友的名字以及他的糖果数量。

思路:

首先我们要知道什么时候糖果数为最多,这时就需要反素数打表了。

反素数:一个区间内存在一个数x,x的因子数大于区间内任何一个数的因子数我们把它称作反素数。

怎么求?直接打表就行了,它又不会随着数据的变化而变化。

之后用线段树去模拟过程找出第x个人就行了。

至于查找的思路去看看这篇blog:http://www.cnblogs.com/CheeseZH/archive/2012/04/29/2476134.html


示例程序

Source Code

Problem: 2886		Code Length: 1604B
Memory: 12344K		Time: 1079MS
Language: GCC		Result: Accepted
#include <stdio.h>
struct
{
int val;
char name[11];
}a[500001];
int x[40]={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,500001};
int gx[40]={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,0};
int pos,line[2000000];
void bulid(int t,int l,int r)
{
int mid;
line[t-1]=r-l+1;
if(l==r)
{
return;
}
mid=(l+r)/2;
bulid(t*2,l,mid);
bulid(t*2+1,mid+1,r);
}
void update(int t,int l,int r,int k)
{
int mid;
line[t-1]--;
if(l==r)
{
pos=l;
return;
}
mid=(l+r)/2;
if(line[t*2-1]>=k)
{
update(t*2,l,mid,k);
}
else
{
update(t*2+1,mid+1,r,k-line[t*2-1]);
}
}
int main()
{
int n,m,k,i,i1,max;
while(scanf("%d %d",&n,&k)!=EOF)
{
for(i=1;n>=i;i++)
{
scanf("%s %d",a[i].name,&a[i].val);
}
bulid(1,1,n);
i=0;
while(n>=x[i])
{
i++;
}
max=gx[i-1];
i=x[i-1];
m=n;
while(i!=0)
{
m--;
i--;
update(1,1,n,k);
if(m==0)
{
break;
}
if(a[pos].val>0)			//顺时针
{
k=(k+a[pos].val-2)%m+1;
}
else				//逆时针
{
k=((k+a[pos].val-1+m)%m+m)%m+1;
}
}
printf("%s %d\n",a[pos].name,max);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: