求最小数(1s)
给出两个正整数P和K,求最小的N使得 P=[N/K] * 3 + [N / 3].除法都是下取整。
输入:
第一行,数据组数。
接下来每行一组数据,P和K
P不超过1000000,K大于3且不超过100。
输出:
每组数据输出一行N。
如果无解输出-1
样例输入:
5
5 4
1 4
13 6
13 17
122 21
样例输出:
6
3
-1
30
258
解析:
首先谈谈我对这道题的感觉,我试图找到一个公式,可是找来找去,又不知从何下手。
其次:问题的关键在于在程序运算中,整数间的除法时是取整运算的因此只能从枚举;
最后:寻找高效的枚举法,就是二分法。(1——1000000);
(补充):由于取整的特性可知,利用二分法取到的数字还可以加以完善,最终得到最小值!!
PS:不要思维定式掉了,没那么复杂,越是精辟的算法,越是简洁!!!
#include<stdio.h>
int main()
{
freopen("in5.txt","r",stdin);
freopen("out5.txt","w",stdout);
int p,k,n,t;
int mid,low,high;
int ok;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&p,&k);
low=1;
high=10000000;
ok=0;
while(low<high)//二分法模板
{
mid=low+(high-low)/2;
if(p==mid/k*3+mid/3)
{ok=1;
n=mid;
break;
}
else if(mid/k*3+mid/3>p)
high=mid;//这里需注意
else
low=mid+1;//前进一步
}
if(ok)
{
while(p==n/k*3+n/3)//由于是整数取整的运算,因此,这里多加一步作为补充,使其取到最小值
{n--;}
printf("%d\n",n+1);
}
else
printf("-1\n");
}
return 0;
}