poj:Fair Distribution
#题目描述
#大概意思要你找到一个最短的方式来使得n * k = m 成立 n只能减小 m只能增加 k为任意一整数
#n减少的数加上m增加的数的和最小
#看着好像只能暴力的算 但是定睛一看 范围 1e8 直接暴力能想到会超时 自己写也是各种优化都来试试撞运气还是卡时间 还要优化算法
#知识点
分块 (我是没看出来-别的大佬说的(⊙ˍ⊙))
#代码
#include<bits/stdc++.h>
using namespace std;
#define maxn 1e9
int n,m;
int main()
{
int t;
cin >> t;
for(int i=1; i<=t; i++)
{
cin >> n >> m;
if(m % n == 0)
{
cout << 0 <<endl;
continue;
}
if(m < n)
{
cout <<n - m <<endl;
continue;
}
else//问题是咋这样想啊 一般都都只会想到下面的i是x 这个将temp也用上了 能用temp 就用temp 否则就用i
{
int ans = maxn;
for(int i=1; i<=n&&i*i <= m; i++) ///!!! i*i 关键 这个限制条件效果很好
{
int temp = (m+i-1)/i;///向上取整 temp 和 i 都有可能是x x * k = m
if(n >= temp)//temp 是x
{
int cnt = (m + temp - 1)/temp;//cnt 是 k 向上取整过的 所以*x后 会大于m
ans = min(ans, min(n-i,n-temp+cnt*temp - m));//min 中 n-i为整除的情况 后一种就是正常情况
}
else // i 是x temp 太大了 不能为n x应该小于n
{
ans = min(ans,n-i+i*temp-m);//!!! 这个temp是向上取整过的 否则要 n-i + m - m%i
}
}
cout << ans <<endl;
}
}
return 0;
}
#总结
学习了大佬的算法 一眼看过去看不懂 蒟蒻(汗 ~ : P)自己分析了好久才弄的 但是还是不知道为什么要这样弄 先学会了再说吧 不会就自己带个数据跑一遍就又会了一点点 (⊙.⊙) 就嗯推 没那个悟性