hdu4611-模拟-思维

给一个t,表示数据有多少组;
在给一个 m,A B;
m是 0到m-1个球,球号也是;
A是 体积为A的箱子,如果 如果 a==i%A 那么就把i球放到a箱子里
0<=a<=A-1;
B和A一样;
球每个球 的 sum+=abs(a-b);
在A箱子的箱号 减去B箱子的箱号的 绝对值,相加输出;
(1<=m<=1000000000, 1<=A,B<=100000)
真的好像c语言题。
但是数据特别大

用模拟的方法;
an 表示当前行(一行A个数)还有 多少空的位置。
并且发现 每一个球的差值其实是 A-B 或者是0
,所以直接计算最小比较的长度就行了。
这里写图片描述
还有要注意,len乘的是 au-bu;而不是a-b;
因为a-b永远有值,但是au-bu看处理情况而定。。。

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
//二分图的完全匹配问题。
//感觉自己的模拟水平还too young,too naive;
using namespace std;
long long solve(long long l,long long  a,long long  b)
{  //注意数据是到不了l的,因为是从0开始的。
    long long au=0;
 long long bu=0;
  long long cnt=0;
   long long ans=0;
   long long len;
   while(cnt<l)
   {  len=min(a-au,b-bu);//未处理过的,谁占的次数最少。
       if(len+cnt>=l) len=l-cnt;//如果超界就截取一下;
       ans+=(long long )abs(au-bu)*len;
       au+=len;
       bu+=len;
       if(au>=a) au-=a;
       if(bu>=b) bu-=b;
       cnt+=len;
   }


return ans;
}
long long  gcd(long long  a,long long b)
{
     if (b==0)
        return a;
    return gcd(b,a%b);
}
long long  lcm(long long  a,long long  b)
{
    long long  c = gcd(a,b);
    return a/c*b;
}
int main()
{  int T;
   long long  m,a,b;
    scanf("%d",&T);
    while(T--)
    {   scanf("%lld%lld%lld",&m,&a,&b);
    if(a==0&&b==0)
    {printf("0\n");
     continue;
    }
        long long  n=lcm(a,b);
        //printf("lcm  %d\n",n);
        if(m<n)
        {
            printf("%lld\n",solve(m,a,b));
            continue;
        }
        else
        {   long long  l=m/n;
            long long  t=m%n;
            //printf("%d  %d**\n",l,t);
            long long  sum=solve(t,a,b)+solve(n,a,b)*l;
            printf("%lld\n",sum);
            continue;
        }
        //cout<<solve(m,a,b)<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值