A triangle is a Heron’s triangle if it satisfies that the side lengths of it are consecutive integers t−1, t, t+ 1 and thatits area is an integer. Now, for given n you need to find a Heron’s triangle associated with the smallest t bigger
than or equal to n.
Input
The input contains multiple test cases. The first line of a multiple input is an integer T (1 ≤ T ≤ 30000) followedby T lines. Each line contains an integer N (1 ≤ N ≤ 10^30).
Output
For each test case, output the smallest t in a line. If the Heron’s triangle required does not exist, output -1.
Sample Input
4
1
2
3
4
Sample Output
4
4
4
4
题目大意:三角形的边分别为i-1, i, i+1,它的面积是整数。输出最小的一个i,使其大于等于n。
题解:首先一定要注意它到底能不能构成三角形!!!i=1,2的时候都不能构成三角形。emmm然后就是找规律了。我列举了1e6范围内满足这个条件的所有i,然后完全发现不了规律……后来队友告诉我计算的时候如果i很大的话结果会出错orz,于是我们只用了前面的数据找规律,然后发现f[i]=4*f[i-1]+f[i-2]...之后就是坑爹的数据范围,不得不用大数来做= =感觉写的大数还有一些问题,到第80个这样的三角形之后i出现了负数……emmm还好没有用到那里的,于是我只保留了前53个,刚好满足10^30的条件,我记得是到了一共有31位数的时候。。如果不留到31的话输入99999……(30个)就会WA。。题上的-1基本可以忽略了,不存在这种输出。
感觉这种列举的方法挺好的……手算真的要算到地老天荒吧。
AC代码:
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
int f[100][40];
int cnt[100];
int main()
{
int i, j;
memset(f, 0, sizeof(f));
memset(cnt, 0, sizeof(cnt));
f[0][0]=4;
cnt[0]=1;
f[1][0]=4, f[1][1]=1;
cnt[1]=2;
for(i=2; i<70; i++)
{
for(j=0; j<cnt[i-1]; j++)
{
f[i][j]+=f[i-1][j]*4-f[i-2][j];
if(f[i][j]>=10)
{
f[i][j+1]=f[i][j]/10;
f[i][j]=f[i][j]%10;
}
else if(f[i][j]<0)
{
f[i][j+1]=-1;
f[i][j]+=10;
}
}
cnt[i]=cnt[i-1];
if(f[i][cnt[i]]!=0)
cnt[i]++;
cout<<cnt[i]<<' ';
for(j=cnt[i]-1; j>=0; j--)
{
cout<<f[i][j];
}
cout<<endl;
}
int t;
cin>>t;
long long n;
int c;
int nx[40];
while(t--)
{
cin>>n;
c=0;
memset(nx, 0, sizeof(nx));
while(n>=10)
{
nx[c]=n%10;
n=n/10;
c++;
}
int pos=0;
bool flag=0;
for(i=0; i<100; i++)
{
if(cnt[i]>c || flag)
{
break;
}
if(cnt[i]==c)
{
for(j=c-1; j>=0; j++)
{
if(f[i][j]>=nx[j])
{
pos=i;
flag=1;
break;
}
}
}
}
for(j=cnt[pos]-1; j>=0; j--)
{
cout<<f[pos][j];
}
cout<<endl;
}
return 0;
}
列举i的代码:(for循环i的范围要改小,不然输出的结果有误)
#include <iostream>
#include <cmath>
using namespace std;
#define LL long long
double cal(LL a, LL b, LL c)
{
double p=(a+b+c)*1.0/2;
return sqrt(p*(p-a)*(p-b)*(p-c));
}
int main()
{
double ans;
for(LL i=3; i<1e6; i++)
{
ans=cal(i-1, i, i+1);
if(ceil(ans)==floor(ans))
cout<<i<<endl;
}
return 0;
}