问题 H: 22-函数-2-真假硬币
题目描述
小南利用周末的时间去帮助菜场的李叔卖菜,收到了一个一元的假硬币,晚上结账时不小心把它混进一堆真币里面去了。现在知道假币的重量比真币的质量要轻。现在有一个天平,我们知道从n个硬币中找出假币的方法有很多种,最简单的就是两两称重穷举的方法,称重n/2次就可以找出来。但是老师希望小南用最快的速度也就是最少的称重次数把那个假币找出来,你能帮他算算最少的称重次数是多少吗?
输入
多样例。每个样例输入一行,包括一个正整数n(1≤n≤230),表示硬币的数目。当输入的n为0时,结束样例输入。
输出
每个测试样例输出一个正整数,表示最少的称重次数。
样例输入 Copy
3 12 0
样例输出 Copy
1 3
提示
假设有3枚硬币,可以任意取2个放天平上称量一下。
因为假币的重量比较轻。
如果天平不平衡,则较轻的那枚就是假币。
如果天平平衡,则说明这两枚硬币都是真的,而剩下那枚是假币。
所以3枚硬币的最少称重次数是1次,那么4枚呢?5枚呢?可以找出硬币数与称重次数之间的关系。
#include<stdio.h>
#include<stdlib.h>
#include<math.h>//调用pow函数需要的头文件
int main()
{
int n=0;
while(scanf("%d",&n)!=EOF)
{
int flag=0;
if(n==0)break;
else
{
while(pow(3,flag)<n)
{
flag++;
}
printf("%d\n",flag);
}
}
return 0;
}
1、pow函数的应用
pow(x,y)函数的用法及实现算法_蚂蚁辣舞的博客-CSDN博客_pow函数
2、时间超限:
原因:num可能超过int范围,变为负数陷入死循环。
改正:long long num
int num=0;
while(num<n)
{
flag++;
num=pow(3,flag);
}
更优解法:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>//调用pow函数需要的头文件
int main()
{
int n=0;
while(1)
{
scanf("%d",&n);
int flag=0;
if(n==0)break;
if(n==1){
printf("0\n");
continue;
}
// 考虑 n==1
long long num=1;
//注意 long long
// 乘3可能超int
while(num<n){
flag++;
num*=3;
}//比用pow函数减少重复计算
printf("%d\n",flag);
}
return 0;
}