• HDU 4611Balls Rearrangement(思维)


    Balls Rearrangement

    Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
    Total Submission(s): 1661    Accepted Submission(s): 627

    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个球编号0~n-1,先放进a个箱子里,i mod a =p,第i个球放在箱子p里面,就是同模的放在一起。然后再把这些球移到b个箱子里面,同样的法则。sum值等于每个球从i号箱子移到j号箱子的数目总和。一个球的sum=abs(i-j).

              解题思路:开始把他想简单了,这些球都是有唯一的标识的。后来想清楚了之后,发现循环节是mi(n,lcm(a,b))但是直接用循环节统计会TLE。如果a取9999,b取9997,n=10^9那么循环节直接是10^9。肯定会TLE。然后又开始找规律,突然发现可以用两个指针不断地移动。不用每次都是++,自己可以在纸上画一下。
    0 1 2 3 4     0 1 2
    5 6 7 8 9     3 4 5
    10            6 7 8
                  9 10
    如果到6的时候,左边一行可以到9,右边一行可以到8.我们选取小的。会发现6~8之间abs(i-j)是一样的。同理0可以直接跳到3那里。主要就是用到这个思想。详见代码。当时因为没有用__int64Wa了好半天!!!

              题目地址:Balls Rearrangement

    AC代码:
    0 1 2 3 4     0 1 2
    5 6 7 8 9     3 4 5
    10            6 7 8
                  9 10
    
    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    __int64 f(__int64 x)
    {
        if(x<0)
            x=-x;
        return x;
    }
    __int64 gcd(__int64 m,__int64 n)
    {
        __int64 t;
        while(n)
        {
            t=m%n; m=n; n=t;
        }
        return m;
    }
    
    __int64 min1(__int64 x1,__int64 x2)
    {
        if(x1<x2) return x1;
        else return x2;
    }
    
    int main()
    {
        __int64 mi,p,a,b,i,j,t1,t2,cnt,sum,tes;
        __int64 lcm;
        scanf("%I64d",&tes);
        while(tes--)
        {
            scanf("%I64d%I64d%I64d",&p,&a,&b);
            if(a==b)
            {
               puts("0");
               continue;
            }
            lcm=a/gcd(a,b)*b;   //a,b的最小公倍数
            mi=p;
            if(mi>lcm)
                mi=lcm;   //mi是循环节
            t1=p/mi,t2=p%mi;
            cnt=0,i=0,j=0;
            sum=0;
    
            __int64 mi2;
            while(cnt<mi)  //一个循环内的
            {
                if(i>=a) i-=a;
                if(j>=b) j-=b;
                mi2=min1(a-i,b-j);
                if(mi2>mi-cnt)  //这点需要注意,不能超过步数
                    mi2=mi-cnt;
                sum+=f(i-j)*mi2;
                i+=mi2; j+=mi2; cnt+=mi2;
            }
            sum=sum*t1;
            cnt=0,i=0,j=0;
            while(cnt<t2)  //循环节以外的
            {
                if(i>=a) i-=a;
                if(j>=b) j-=b;
                mi2=min1(a-i,b-j);
                if(mi2>t2-cnt)
                    mi2=t2-cnt;
                sum+=f(i-j)*mi2;
                i+=mi2; j+=mi2; cnt+=mi2;
            }
            printf("%I64d
    ",sum);
        }
        return 0;
    }
    
    /*
    23
    1000000000 1 1
    8 2 4
    11 5 3
    1000000000 9999 9997
    */
    


  • 相关阅读:
    codeforces #601 div2 ABC~E1
    codeforces #600 div2 ABCD
    图形学 三次Hermite曲线绘制实现代码 javascript:es6+h5:canvas
    最小生成树(Prim / Kruskal)
    拓扑排序【Kahn算法(bfs)和dfs求拓扑序列及判环】
    Cow Traffic(正反向建图+DAG拓扑排序)
    JAVA大数
    【C/C++】关于strstr函数和c_str()函数
    【C/C++】关于函数调用传递实参
    2019上海icpc网络赛B. Light bulbs(思维+差分)
  • 原文地址:https://www.cnblogs.com/james1207/p/3281349.html
Copyright © 2020-2023  润新知