题目是这样的,一个等边三角形,三边都是有镜子组成的。
现在要你从一个点射入一条光线,问你如果要求光线在三角形里面反射n次然后从入点射出来的话,入射的方向可能有多少种?
这。。。。。其实不难。关键是要搞清楚镜子反射的规律。
这样来理解。反射的话相当于在另一面也是一个三角形,这样我们可以把同样的等腰三角形铺满整个二维空间。
这样就会发现规律,如果我们把所有的点都分层,那么发现射到第一层的反射次数为1,第二层为3,第三才层为5,这样下来我们就可以知道如果要反射n次射出的那个对称点应该在那个层数了。
到此我们唯一的问题就是求出每一层有多少个点了。
但是有多少个点就是答案吗? 不是的,如果后面的点被前面的点遮挡了,那么那个点是不算的。
嗯大概就是这样。 基本的解法就是这样的了。。。 只是个人想法。求指教。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#define ll long long
using namespace std;
ll t,n;
map<ll,ll> g;
ll f(ll x)
{
if (x%2==0) return 2*(x/6+1)-1;
else return 2*((x-3)/6+1);
}
ll get(ll x)
{
if (g[x]!=0) return g[x];
g[x]=f(x);
for (ll i=2; i*i<=x; i++)
{
if (x%i>0) continue;
g[x]-=get(i);
if (i*i!=x)
{
g[x]-=get(x/i);
}
}
return g[x];
}
int main()
{
scanf("%I64d",&t);
while (t--)
{
scanf("%I64d",&n);
if (n%3==0)
{
printf("0
");
continue;
}
if ((n&1)==0)
{
printf("0
");
continue;
}
if (n==1)
{
printf("1
");
continue;
}
if (n==3)
{
printf("0
");
continue;
}
n=(n+3)>>1;
printf("%I64d
",get(n));
}
return 0;
}