您的位置:首页 > 其它

poj 3090 Visible Lattice Points

2016-07-22 11:04 302 查看
   题意:  给你一个n*n的网格,任意一点和(0,0)连线,可以组成一条直线,前面的点可以挡住后面的点,问你能看到的多少个点。

   思路:我们可以想到每一个点坐标(x,y)与(kx,ky)在同一条线上,这样的话比如在(0,0)点观察y=2x方向就只能看到(1,2)点,(2,4)点就会被挡住。观察到的这些点的坐标我们可以看到横坐标和纵坐标两个数是互素的。

   寻找横纵坐标互素的方法:两个数的最大公约数为1.< gcd(a,b)==1  >

   注意:网格是对称的,所以选择一半扫一遍计数就可以,最后乘2。不要忘记x和y轴,y=x方向上还有3个点。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int gcd(int a,int b)
{
return (b==0)?a:gcd(b,a%b);
}
int main()
{
bool visit[1005][1005]; //互质标记数组
memset(visit,false,sizeof(visit));
for(int i=1;i<=1005;i++)
for(int j=i+1;j<=1005;j++)
{
if(gcd(i,j)==1) visit[i][j]=true; //最大公约数为1则两个数互质,将该点标记
}
int C,cas=0;
scanf("%d",&C);
while(C--)
{
int size,ans=0;
scanf("%d",&size);
for(int i=1;i<=size;i++)
for(int j=i+1;j<=size;j++)
{
if(visit[i][j]==true) ans++; //遍历边长为size的网格,用ans计数找到满足条件坐标的个数
}
printf("%d %d %d",++cas,size,ans*2+3);
if(C) printf("\n");
}
return 0;
}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: