题目链接ZOJ:4160:Fair Distribution
题面:
样例输入:
3
3 12
10 6
8 20
样例输出 :
0
4
2
对整除分块的详解不赘述,可以看这篇博客,讲的很好:整出分块
讲解中“[x/y]”表示x整除y
该题中将式子做出转换。可以发现n只能减,而m只能加,那么假设n最终减到x,那么m要加到某个最近的能整除x的位置,该位置即为([(m-1)/x]+1)*x,那么最终步数为n-x+([(m-1)/x]+1)*x-m;
将式子进行整理,便可得到答案为n-m+[(m-1)/x]*x,那么求这个式子的最小值就行,所以进行整除分块,若[l , r]表示的是某个分块的范围,那么x在这个范围内[(m-1)/x]为定值,那么去x最小即为l就行。所以求每个分块中[(m-1)/l]*l的最小值即可。
注:x是一定是小于等于n的,所以在跑循环的时候要加此限定条件
代码段:
#include <bits/stdc++.h>
using namespace std;
int n,m;
int get_min(){
int ans=0x3f3f3f3f;
for(int l=1,r;l<=n;l=r+1){
r=(m-1)/((m-1)/l);
ans=min(ans,(m-1)/l*l);
}
return ans;
}
int main(){
int T;cin>>T;
while(T--){
cin>>n>>m;
if(n>m) cout<<n-m<<endl;
else if(m%n==0) puts("0");
else{
cout<<n-m+get_min()<<endl;
}
}
return 0;
}