求最小数

求最小数(1s

给出两个正整数P和K,求最小的N使得 P=[N/K] * 3 + [N / 3].除法都是下取整。

输入:

第一行,数据组数。

接下来每行一组数据,P和K

P不超过1000000K大于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;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值