Sample Input
5
1 3
2 11
3 12
4 100
5 9999
Sample Output
1 l
2 5
3 4
4 392
5 4165834
题意:给一段篱笆,要求建一个三角形的鸡舍,不能有剩余,等腰三角形、等边三角形(等边三角形就是等腰三角形)视为一种方式,其他三角形视为两种方式,问一共可以有几种方式。
思路:默认x<=y<=z,先遍历最短的边长x,范围是1到n/3,求出y可能的范围,先默认为是普通的三角形,最后判断在减去。
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
const int MAX=3e7+7;
deque <ll> dq;
typedef long long ll;
//int a[MAX]={0};
int main()
{
ll x,n,T,e;
cin>>T;
while(T--)
{
cin>>e>>n;
ll ymin,ymax;
ll ans=0;
for(x=1;x<=n/3;x++)//遍历最短的一条边
{
ymin=max(n/2-x+1,x);//y的最小取值范围(1)
ymax=(n-x)/2;//(2)
ans+=(ymax-ymin+1)*2;//(3)
if(x==ymin)//(4)
ans--;
if(x!=ymax&&ymax==n-x-ymax)//(5)
ans--;
}
cout<<e<<" "<<ans<<endl;
}
}
解释一下上面的代码:(1)根据两边之和小于第三边,z-y<x (z=n-x-y) 得 y>x-n/2 所以y的取值范围是 y>x-n/2+1.
(2)y的最大取值
(3)默认都是普通的三角形,乘以2
(4)x==y的情况,因为x<=y<=z所以要想x==y只可能等于y的最小值。
(5)判断y==z的情况,默认不是等边三角形,y的最大取值为z.