标签:des style blog http io os ar for sp
Greater New York 2006Visible Lattice Points
题目大意:现在有一个二维坐标系,只有离散的整数坐标上有点。
现在站在N点向周围看去。问能看到多少个点。
假如看到了(2,1),那么(2,1)后边的(4,2)(6,3)…就被挡住
看不到了。
考虑1*1的时候,有三个点(1,0)(1,1)(0,1)。
(1,0)和(0,1)关于(1,1)对称
再看2*2的时候,有个点(1,0)(1,1)(2,1)(0,1)(1,2)
(1,0)和(0,1)关于(1,1)对称
(2,1)和(1,2)关于(1,1)对称
比1*1多了两个点。并且都是关于(1,1)对称,而(2,2)则被(1,1)遮挡住了
所以我们只考虑下三角的情况。得出结果*2+1就是最终答案。
因为同斜率的点都被第一个点盖掉看不到了,所以我们只考虑斜率有多少种就是得出结果了。
1*1的时候,斜率有0
2*2的时候,斜率有0,1/2
3*3的时候,斜率有0,1/2,1/3,2/3
4*4的时候,斜率有0,1/2(2/4),1/3,2/3,1/4,3/4;
5*5的时候,斜率有0,1/2(2/4),1/3,2/3,1/4,3/4,1/5,2/5,3/5,4/5
6*6的时候,斜率有0,1/2(2/4,3/6),1/3(2/6),2/3(4/6),1/4,3/4,1/5,2/5,3/5,4/5,1/6,5/6
可以看出,其实就是求分母小于等于N的真分数有多少
那么就是单纯的欧拉函数了,这里用普通欧拉函数和快速求欧拉函数都可以
参考博文:http://blog.csdn.net/zhang20072844/article/details/8108727
#include<stdio.h>
int prime[1010],phi[1001];
bool unprime[1010];
void Euler()//快速求欧拉函数
{
int i,j,k = 0;
for(i = 2; i <= 1000; i++)
{
if(!unprime[i])
{
prime[k++] = i;
phi[i] = i-1;
}
for(j = 0; j < k && i*prime[j] <= 1000; j++)
{
unprime[prime[j]*i] = true;
if(i % prime[j] != 0)
phi[prime[j]*i] = phi[i] * (prime[j]-1);
else
{
phi[prime[j]*i] = phi[i] * prime[j];
break;
}
}
}
}
int main()
{
int C,n;
Euler();
phi[1]=1;
scanf("%d",&C);
int kase = 1;
while(C--)
{
scanf("%d",&n);
int sum = 0;
for(int i = 1;i <= n; i++)
sum += phi[i];
printf("%d %d %d\n",kase++,n,2*sum+1);
}
return 0;
}#include <stdio.h>
#include <math.h>
int Euler(int n)//普通求欧拉函数
{
int i,ret = n;
for(i = 2; i <= sqrt(1.0*n); i++)
{
if(n % i == 0)
{
ret = ret - ret/i;
}
while(n % i == 0)
n /= i;
}
if(n > 1)
ret = ret - ret/n;
return ret;
}
int main()
{
int C,n;
scanf("%d",&C);
int kase = 1;
while(C--)
{
scanf("%d",&n);
int sum = 0;
for(int i = 1;i <= n; i++)
sum += Euler(i);
printf("%d %d %d\n",kase++,n,2*sum+1);
}
}
POJ3090_Visible Lattice Points【欧拉函数】
标签:des style blog http io os ar for sp
原文地址:http://blog.csdn.net/lianai911/article/details/40142277