现在的位置: 首页 > 综合 > 正文

poj2886 Who Gets the Most Candie…

2017年12月13日 ⁄ 综合 ⁄ 共 1459字 ⁄ 字号 评论关闭
题意:N个人围成一圈第一个人跳出圈后会告诉你下一个谁跳出来跳出来的人(如果他手上拿的数为正数,从他左边数A个,反之,从他右边数A个)
跳出来的人所得到的糖果数量和他跳出的顺序有关 所得的糖果数为 (假设他是第k个跳出的) 则他得到的糖数为k能被多少个数正数 比如说 k
= 6 ;  6 = 1*2*3*6 所以他得到的糖数为4;

思路:线段数 先算出N个人中,是第几个人(id)跳出来得到的糖果最多。然后模拟id遍 长到第id个人的name
线段树的结点中保存该区间内还剩多少人,每次update 删除一个人。

//24200K   
1235MS
#include <stdio.h>
#include <string.h>
#define L(x) (x<<1)
#define R(x) (x<<1|1)
const int M = 500010;
int n,id;
struct tree
{
    int l,r,sum;
//sum 表 该区间剩余人数
} node[M*3];

struct data
{
    int
val;
    char
name[15];
} boy[M];

int ans[M]; //ans[i]保存第i个人跳出能得到的糖果数量

void BuildTree (int left,int right,int u)
{
    node[u].l =
left;
    node[u].r =
right;
    node[u].sum
= right - left + 1;
    if (left ==
right)
       
return ;
    int mid =
(left + right)>>1;
   
BuildTree(left,mid,L(u));
   
BuildTree(mid+1,right,R(u));
}
int update (int key,int u)
{
    node[u].sum
--;
    if
(node[u].l == node[u].r)
       
return node[u].l;
    if
(node[L(u)].sum >= key)
       
return update(key,L(u));
    else
       
return update (key - node[L(u)].sum,R(u));
}
void count_ans()
{
    memset
(ans,0,sizeof(ans));  
//计算ans
    for (int i =
1; i <= n; i ++)
    {
       
ans[i] ++;
       
for (int j = 2*i; j <= n; j += i)
           
ans[j] ++;
    }
    int max =
ans[1];
    id =
1;
    for (int i =
2; i <= n; i ++) //找出第几个人跳出获得的糖最多
       
if (ans[i] > max)
       
{
           
max = ans[i];
           
id = i;
       
}
}
int main ()
{
    int
i,k,mod;
    while
(~scanf ("%d %d",&n,&k))
    {
       
count_ans();
       
for (i = 1; i <= n; i ++)
           
scanf ("%s %d",boy[i].name,&boy[i].val);
       
BuildTree (1,n,1);
       
mod = node[1].sum;
       
int pos = 0;
       
boy[0].val = 0;
       
n = id;
       
while (n --)
       
{

抱歉!评论已关闭.