郭姐虽然喜欢一直呆在实验室刷题,但有一个发财的梦想。郭姐终于下决心要出去闯荡了,早就听说隔壁村有一个悬浮于空中的藏宝密室,带上扑克牌和神秘武器来到传说中的指定地点,前门有悬浮于空中的楼梯板直接到达密室门口,但是有胖乎乎的门卫貌似不好惹,郭姐很怂,只能走到后门,来用自己带的超大型的扑克牌如图那样堆叠来爬到密室口,假设郭姐带有n张扑克牌,郭姐想知道最多能堆多少层来确定是否自己能够爬到密室口。
输入描述
多组输入。
每组数据只包含一个数字n。(0<=n<=1008612345678)输出描述
对于每组数据输出一行,每行一个数字即最多层数。
样例输入
2 7
样例输出
1 2
来源
2016年中北大学新生赛
题是不难,,,关键有坑,开始用的double,然后wa了,用float ,向下取整到是没问题,也wa了……(什么输出方式都无法挽救wa的事实)
问题是改成long double就ac了,输出用llf或者cout
附上代码
#include<cstdio>
#include<string>
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
long long n;
while(~scanf("%lld",&n))
{
float m=0;
if(n==1||n==0)
printf("0\n");
else if(n==2)
printf("1\n");
else
{
m=sqrt((float)2.0/(float)3.0*n+(float)1.0/(float)36.0)-(float)1.0/(float)6.0;
if(m==(int)m)
printf("%.f\n",m);
else
printf("%.f\n",floor(m));
}
}
return 0;
}
原因:double精度有问题,double存储可能是1.999999999999999999,向下取整就出问题了,至于float为什么没过,是平台问题,最好用double,long double精度就没啥问题 了
#include<cstdio>
#include<string>
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
long long n;
while(~scanf("%lld",&n))
{
long double m=0;
if(n==1||n==0)
printf("0\n");
else if(n==2)
printf("1\n");
else
{
m=sqrt((long double)2.0/(long double)3.0*n+(long double)1.0/(long double)36.0)-(long double)1.0/(long double)6.0;
cout<<floor(m)<<endl;
}
}
return 0;
}
或者吧,这样子也能ac,
#include<cstdio>
#include<string>
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
long long n;
while(~scanf("%lld",&n))
{
double m=0;
m=(double)(sqrt(24*n+1)-1)/6.0;
if(m==(int)m)
printf("%.f\n",m);
else
printf("%.f\n",floor(m));
}
return 0;
}
cin输出也可以;
原因就是精度问题,如果化简式子,sqrt里面全为整数,不存在小数点后为9999999的情况,因为7,15等数字未化简之前的式子中,算出的结果只是无限接近于期望值,且小于期望值,因此,向下取整得到结果为1;float嘛,虽然代码测试样例是正确的,其实还是精度问题,保不准也出现了999999的情况,还有好多平台不太支持用float,也不是不支持,只是容易wa