• HDU 4611 Balls Rearrangement


    Balls Rearrangement

    Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)

    Total Submission(s): 1079    Accepted Submission(s): 416

    Problem Description
      Bob has N balls and A boxes. He numbers the balls from 0 to N-1, and numbers the boxes from 0 to A-1. To find the balls easily, he puts the ball numbered x into the box numbered a if x = a mod A.   Some day Bob buys B new boxes, and he wants to rearrange the balls from the old boxes to the new boxes. The new boxes are numbered from 0 to B-1. After the rearrangement, the ball numbered x should be in the box number b if x = b mod B.   This work may be very boring, so he wants to know the cost before the rearrangement. If he moves a ball from the old box numbered a to the new box numbered b, the cost he considered would be |a-b|. The total cost is the sum of the cost to move every ball, and it is what Bob is interested in now.
     
    Input
      The first line of the input is an integer T, the number of test cases.(0<T<=50)    Then T test case followed. The only line of each test case are three integers N, A and B.(1<=N<=1000000000, 1<=A,B<=100000).
     
    Output
      For each test case, output the total cost.
     
    Sample Input
    3
    1000000000 1 1
    8 2 4
    11 5 3
     
    Sample Output
    0
    8
    16
     
    Source
     

    多校第二场的第一题。

    对给定的n,a,b,求对每一个i(1<=i<=n),(i%a-i%b)的绝对值的和。

    如果直接暴力从1到n求解必然超时

    但是我们很快就会发现,(i%a-i%b)的值是周期性出现的,周期为lcm(a,b)。

    可对于很大并且互素的a,b来说,它们的最小公倍数可能非常大,导致这个周期可能只出现一次,这样的话就又和直接暴力没什么区别了。(比赛时就卡在这里...)

    后来比赛后看了学姐的博客,发现到这依然可以进一步优化:

    对于每一个周期的区间,我们又可以把它划分为多个子区间,在每个子区间内(i%a-i%b)的值是相等的,这样我们中要在一个周期的区间内扫描这样的子区间就可以了,复杂度为O(a+b),是可以接受的。

    另外数据要用long long保存,不知道为什么,数据范围明明在long以内,可是交上去就是WA,还是后来一位学长给我改了过来

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #define LL long long
      5 
      6 using namespace std;
      7 
      8 LL gcd (LL x, LL y)
      9 {
     10     LL z;
     11     if (x < y)
     12         x ^= y ^= x ^= y;
     13     while (y)
     14     {
     15         z = x % y;
     16         x = y;
     17         y = z;
     18     }
     19     return x;
     20 }
     21 
     22 LL lcm (LL x, LL y)
     23 {
     24     return x * y / gcd (x, y);
     25 }
     26 
     27 long long cal (LL n, LL a, LL b)
     28 {
     29     if (a == b)
     30         return 0;
     31     LL current = 0, atimes = 0, btimes = 0, t = lcm (a, b), times = n / t;
     32     long long ans = 0;
     33     if (times)
     34     {
     35         while (current < t)
     36         {
     37             if ( (atimes + 1) *a < (btimes + 1) *b)
     38             {
     39                 atimes++;
     40                 ans += fabs (int (current % a - current % b)) * (atimes * a - current);
     41                 current = atimes * a;
     42             }
     43             else
     44             {
     45                 btimes++;
     46                 ans += fabs (int (current % a - current % b)) * (btimes * b - current);
     47                 current = btimes * b;
     48             }
     49         }
     50         ans *= times;
     51     }
     52     current = 0;
     53     atimes = btimes = 0;
     54     LL am, bm, e = n - t * times - 1;
     55     while (current <= e)
     56     {
     57         am = (atimes + 1) * a;
     58         bm = (btimes + 1) * b;
     59         if (am < bm)
     60         {
     61             if (am <= e)
     62             {
     63                 ans += fabs ( (int) current % a - current % b) * (am - current);
     64                 current = am;
     65                 atimes++;
     66             }
     67             else
     68             {
     69                 ans += fabs (int (current % a - current % b)) * (e - current + 1);
     70                 break;
     71             }
     72         }
     73         else
     74         {
     75             if (bm <= e)
     76             {
     77                 ans += fabs (int (current % a - current % b)) * (bm - current);
     78                 current = bm;
     79                 btimes++;
     80             }
     81             else
     82             {
     83                 ans += fabs (int (current % a - current % b)) * (e - current + 1);
     84                 break;
     85             }
     86         }
     87     }
     88     return ans;
     89 }
     90 
     91 int main()
     92 {
     93     int t;
     94     LL n, a, b;
     95     scanf ("%d", &t);
     96     while (t--)
     97     {
     98         scanf ("%I64d %I64d %I64d", &n, &a, &b);
     99         printf ("%I64d
    ", cal (n, a, b));
    100     }
    101     return 0;
    102 }
    [C++]
  • 相关阅读:
    ride关键字
    怎么分析《软件需求文档》
    linux系统在线搭建禅道
    用fiddler不能抓取https及证书无法导出
    mybatis There is no getter for property named 'xx' in 'class java.lang.String
    GMT与UTC
    cron表达式详解
    hdu 2083 简易版之最短距离
    hdu 2070 Fibbonacci Number
    hdu 2076 夹角有多大(题目已修改,注意读题)
  • 原文地址:https://www.cnblogs.com/lzj-0218/p/3219761.html
Copyright © 2020-2023  润新知