【數學規律】Visible Lattice Points(規律題)

Visible Lattice Points

題目鏈接(點擊)

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 9031   Accepted: 5490

Description

A lattice point (xy) in the first quadrant (x and y are integers greater than or equal to 0), other than the origin, is visible from the origin if the line from (0, 0) to (xy) does not pass through any other lattice point. For example, the point (4, 2) is not visible since the line from the origin passes through (2, 1). The figure below shows the points (xy) with 0 ≤ xy ≤ 5 with lines from the origin to the visible points.

Write a program which, given a value for the size, N, computes the number of visible points (xy) with 0 ≤ xy ≤ N.

Input

The first line of input contains a single integer C (1 ≤ C ≤ 1000) which is the number of datasets that follow.

Each dataset consists of a single line of input containing a single integer N (1 ≤ N ≤ 1000), which is the size.

Output

For each dataset, there is to be one line of output consisting of: the dataset number starting at 1, a single space, the size, a single space and the number of visible points for that size.

Sample Input

4
2
4
5
231

Sample Output

1 2 5
2 4 13
3 5 21
4 231 32549

思路:

問題:從原點出發的射線從x軸開始逆時針旋轉,如果射線穿過某點則這個點 則該點可以被看到 求可以看到的點的個數總和

知道這個題是有規律(找到斜率相同且最先出現的點)直接看 看了好久也沒找到,最後自己索性把所有要被與原點相連接的點打印出來 就可以看出來了

輸出如圖:

三個值分別表示:

  x   y   k

規律:如果x是奇數(例如x=7) 需要滿足gcd(x,y)==1的點 若是偶數同理

即:x與y互質 (佩服同學能直接看出來互質……)

下面是找規律的代碼:

#include<stdio.h>
#include<algorithm>
using namespace std;
typedef long long LL;
const int MAX=1e6;
struct node{
    double count2;
    LL x;
    LL y;
}num[MAX+5];
struct node1{
    LL x1;
    LL y1;
    double num3;
}edge[MAX+5];
bool cmp(node a,node b)
{
    if(a.count2==b.count2){
        return a.x<b.x;
    }
    else{
        return a.count2<b.count2;
    }
}
bool cmp1(node1 a,node1 b)
{
    if(a.x1!=b.x1){
        return a.x1<b.x1;
    }
    return a.y1<b.y1;
}
int main()
{
    LL count,T,n;
    scanf("%lld",&T);
    for(LL k=1;k<=T;k++){
        scanf("%lld",&n);
        count=0;
        for(LL i=2;i<=n;i++){
            for(LL j=1;j<i;j++){
                num[count].count2=(j*1.0)/(i*1.0);
                num[count].x=i;
                num[count].y=j;
                count++;
            }
        }
        sort(num,num+count,cmp);
        LL count1=0,count3=0;
        for(LL i=0;i<count;i++){
            if(num[i].count2!=num[i-1].count2){
                edge[count3].x1=num[i].x;
                edge[count3].y1=num[i].y;
                edge[count3++].num3=num[i].count2;
               // printf("*%lld %lld %.2lf\n",num[i].x,num[i].y,num[i].count2);
                count1++;
            }
        }
        sort(edge,edge+count3,cmp1);
        for(int i=0;i<count3;i++){
            printf("*%lld %lld %.2lf\n",edge[i].x1,edge[i].y1,edge[i].num3);
        }
        if(n==1){
            printf("%lld 1 3\n",k);
        }
        else{
            LL sum=3;
            sum+=count1*2;
            printf("%lld %lld %lld\n",k,n,sum);
        }
    }
    return 0;
}

 

AC代碼:

(找規律接近100行 但AC卻只是40行左右)

#include<stdio.h>
typedef long long LL;
const int MAX=1e5;
int gcd(int a,int b)
{
    if(b==0){
        return a;
    }
    return gcd(b,a%b);
}
int main()
{
    LL num[MAX+5]={0},T;
    num[1]=1;
    for(int i=2;i<=1000;i++){
        LL count=0;
        if(i%2==0){
            for(int j=1;j<i;j+=2){
                if(gcd(i,j)==1){
                    count++;
                }
            }
        }
        else{
            for(int j=1;j<i;j++){
                if(gcd(i,j)==1){
                    count++;
                }
            }
        }
        num[i]=num[i-1]+count;
    }
    scanf("%lld",&T);
    for(LL k=1;k<=T;k++){
        LL n,sum=0;
        scanf("%lld",&n);
        sum+=(num[n]*2+1);
        printf("%lld %lld %lld\n",k,n,sum);
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章