HDU 4710 Balls Rearrangement

这道题太搞笑了,估计是HDU的测试数据太弱了,我直接暴力加一点小技巧都过了,sigh。。。

不过有一点值得注意的是,64位数据最好用cin/cout,否则可能会产生输入和输出错误。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4710

好吧,就是求a,b 的最小公倍数Q,然后如果Q>n,就直接进行上限为Q的模拟,当然,要加一点小技巧。

技巧:设现在要往A,B箱子里放球,箱子编号分别为la,lb,那么剩余量就是A-la,和B-lb。用剩余量最小的那个直接进行加法操作,相见代码。。。

貌似这个技巧叫做跳跃求值,我不知道。。。

如果Q<n,就进行上限为Q的模拟,模拟n/Q次,再模拟一次,上限为n%Q。

总量就是n/Q*calcu(Q,a,b) + calcu(n%Q,a,b) .

上代码:

 1 #include<stdio.h>
 2 #include<iostream>
 3 using namespace std;
 4 #include<math.h>
 5 #include<string>
 6 #include<map>
 7 #include<queue>
 8 #include<stdlib.h>
 9 #include<algorithm>
10 
11 #define repA(p,q,i)  for( int (i)=(p); (i)!=(q); ++(i) )
12 #define repAE(p,q,i)  for( int (i)=(p); (i)<=(q); ++(i) )
13 #define repD(p,q,i)  for( int (i)=(p); (i)!=(q); --(i) )
14 #define repDE(p,q,i)  for( int (i)=(p); (i)>=(q); --(i) )
15 #define ll long long
16 
17 ll gcd(ll a, ll b);
18 ll calcu( ll round, ll ca, ll cb );
19 
20 int main()
21 {
22     ll a,b,n;
23     int test;  scanf("%d",&test);
24     while(test--)
25     {
26         cin>>n>>a>>b ;
27         ll GCD = gcd(a, b) ;
28         ll circle = a*b/GCD ;
29         if(a == b)
30         {
31              printf("0\n");
32              continue;
33         }
34         
35         if( circle > n )
36         {
37             cout<< calcu(n,a,b) << endl ;
38             continue;
39         }
40         ll ans = n/circle * calcu(circle,a,b);
41     
42         ans += calcu(n%circle,a,b);
43         cout<<ans<<endl; 
44         
45     }
46     return 0;
47 }
48 
49 ll gcd(ll a, ll b)
50 {  return b==0?a:gcd(b,a%b);  }
51 
52 
53 ll calcu( ll round, ll ca, ll cb )
54 {
55      ll la=0, lb=0, gone, ans=0;
56      int i=0;
57      while( i < round )
58      {
59          gone = min( ca-la , cb-lb ) ;
60          if( i+gone < round )
61          {
62              i += gone;
63              ans += gone * abs(la-lb) ;
64              la = (la+gone) % ca ;
65              lb = (lb+gone) % cb ; 
66          }
67          else 
68          {
69               ans += (round-i) * abs(la-lb) ;
70               break;
71          }
72      }
73      return ans ;
74 } 
我的代码

当然我以为我的代码应该是野鸡代码,水过去的,不过后来搜了下题解,发现别人的好像跟我差不多思路,代码还没有我简洁。。。。

当然,简洁换来的是速度的下降,本质没什么区别。

贴一下吧,摘自:http://www.cnblogs.com/kuangbin/p/3214791.html

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <string.h>
 5 #include <set>
 6 #include <map>
 7 #include <vector>
 8 #include <queue>
 9 #include <string>
10 #include <math.h>
11 using namespace std;
12 long long gcd(long long a,long long b)
13 {
14     if(b==0)return a;
15     else return gcd(b,a%b);
16 }
17 long long lcm(long long a,long long b)
18 {
19     return a/gcd(a,b)*b;
20 }
21 long long calc(int n,int a,int b)
22 {
23     long long ans = 0;
24     int i = 0;
25     int ta=0,tb=0;
26     int p = 0;
27     while(i < n)
28     {
29         if(ta+a >= n && tb+b >= n)
30         {
31             ans += (long long)(n-i)*p;
32             i = n;
33             continue;
34         }
35         if(ta+a < tb+b)
36         {
37             ans += (long long)p*(ta+a-i);
38             i = ta+a;
39             p = i - tb;
40             ta+=a;
41         }
42         else if(ta+a==tb+b)
43         {
44             ans+= (long long)p*(ta+a-i);
45             i = ta+a;
46             ta+=a;
47             tb+=b;
48             p = 0;
49         }
50         else
51         {
52             ans += (long long)p*(tb+b-i);
53             i = tb+b;
54             tb+= b;
55             p = i-ta;
56         }
57     }
58     return ans;
59 }
60 int main()
61 {
62     //freopen("in.txt","r",stdin);
63     //freopen("out.txt","w",stdout);
64     int T;
65     int n,a,b;
66     scanf("%d",&T);
67     while(T--)
68     {
69         scanf("%d%d%d",&n,&a,&b);
70         if(a==b)
71         {
72             printf("0\n");
73             continue;
74         }
75         if(a < b)swap(a,b);
76         long long LCM = lcm(a,b);
77         if(LCM >= n)
78         {
79             printf("%I64d\n",calc(n,a,b));
80             continue;
81         }
82         long long tmp = calc(LCM,a,b);
83         long long ans = tmp * (n/LCM)+calc(n%LCM,a,b);
84         printf("%I64d\n",ans);
85     }
86     return 0;
87 }
大多数人的代码

 

 

posted on 2013-09-10 21:36  码农之上~  阅读(214)  评论(0编辑  收藏  举报

导航