hdu 4710 Balls Rearrangement
题意就不说了,刚开始做我竟然傻傻地去模拟,智商捉急啊~~超时是肯定的
求出 a ,b 的最小公倍数,因为n够长的话,就会出现循环,所以就不要再做不必要的计算了。如果最小公倍数大于n的话,就直接计算n吧。
除了可以应用循环来节省计算,还可以成段计算来节省。
#include<stdio.h> #include<string.h> #define i64 __int64 i64 abs(i64 x) { if(x<0) return -x; return x; } i64 gcd(i64 a,i64 b) { if(b==0) return a; return gcd(b,a%b); } i64 Deal(i64 len,i64 a,i64 b) { int i=0; i64 ans=0; while(i<len) { int tmp = (a-i%a)>(b-i%b)?(b-i%b):(a-i%a); if(tmp+i>len) tmp=len-i; ans+=abs(i%a-i%b)*tmp; i+=tmp; } return ans; } int main() { i64 N,A,B; int T; i64 ans; scanf("%d",&T); while(T--) { scanf("%I64d%I64d%I64d",&N,&A,&B); if(A==B) { printf("0\n"); continue; } i64 tmp = A/gcd(A,B)*B; if(tmp>N) ans=Deal(N,A,B); else ans=Deal(tmp,A,B)*(N/tmp)+Deal(N%tmp,A,B); printf("%I64d\n",ans); } return 0; }