zoukankan      html  css  js  c++  java
  • poj2886 Who Gets the Most Candies?

    思路:

    先打反素数表,即可确定因子最多的那个数。然后模拟踢人的过程确定对应的人名。模拟的过程使用线段树优化加速。

    实现:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <string>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 const int MAXN = 500005;
     8 
     9 int antiprime[] = {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};
    10 int fac[] = {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};
    11 
    12 int tree[MAXN << 2], num[MAXN], n, k;
    13 char name[MAXN][11];
    14 
    15 void build(int num, int l, int r)
    16 {
    17     if (l == r) { tree[num] = 1; return; }
    18     int m = l + r >> 1;
    19     build(num << 1, l, m);
    20     build(num << 1 | 1, m + 1, r);
    21     tree[num] = tree[num << 1] + tree[num << 1 | 1];
    22 }
    23 
    24 int kick(int num, int l, int r, int x) // 在[l, r]范围内踢掉第x个人
    25 {
    26     if (l == r) { tree[num] = 0; return l; }
    27     int m = l + r >> 1, tmp = tree[num << 1], ans = -1;
    28     if (tmp >= x) ans = kick(num << 1, l, m, x);
    29     else ans = kick(num << 1 | 1, m + 1, r, x - tmp);
    30     tree[num] = tree[num << 1] + tree[num << 1 | 1];
    31     return ans;
    32 }
    33 
    34 int main()
    35 {
    36     while (scanf("%d %d", &n, &k) != EOF)
    37     {
    38         for (int i = 1; i <= n; i++) scanf("%s %d", name + i, num + i);
    39         build(1, 1, n);
    40         int now = k, out = -1, cnt = n;
    41         int tmp = lower_bound(antiprime, antiprime + 36, n) - antiprime;
    42         int w = antiprime[tmp] > n ? tmp - 1 : tmp;
    43         for (int i = 0; i < antiprime[w]; i++)
    44         {
    45             out = kick(1, 1, n, now);
    46             cnt--;
    47             if (!cnt) break;
    48             if (num[out] > 0) now = ((now + num[out] - 1) % cnt + cnt) % cnt;
    49             else now = ((now + num[out]) % cnt + cnt) % cnt;
    50             now = !now ? cnt : now;
    51         }
    52         printf("%s %d
    ", name[out], fac[w]);
    53     }
    54     return 0;
    55 }
  • 相关阅读:
    【复习+知识补充】EL表达式:只能调用静态方法
    【复习】sql语句的拼接 + 链接地址的简写
    淘淘商城maven工程的创建和svn的上传实现
    淘淘商城基于maven和svn的理解
    国家电力项目SSH搭建
    linux中权限的修改
    chown -R命令的使用
    修改nginx的访问目录以及遇到的403错误修改总结
    nginx的在linux系统中的安装
    集群环境的图片的访问和存储
  • 原文地址:https://www.cnblogs.com/wangyiming/p/8460362.html
Copyright © 2011-2022 走看看