可見點acwing201歐拉函數

題目:
在一個平面直角座標系的第一象限內,如果一個點(x,y)與原點(0,0)的連線中沒有通過其他任何點,則稱該點在原點處是可見的。

例如,點(4,2)就是不可見的,因爲它與原點的連線會通過點(2,1)。

部分可見點與原點的連線如下圖所示:

3090_1.png

編寫一個程序,計算給定整數N的情況下,滿足0≤x,y≤N的可見點(x,y)的數量(可見點不包括原點)。
在這裏插入圖片描述
輸入格式
第一行包含整數C,表示共有C組測試數據。

每組測試數據佔一行,包含一個整數N。

輸出格式
每組測試數據的輸出佔據一行。

應包括:測試數據的編號(從1開始),該組測試數據對應的N以及可見點的數量。

同行數據之間用空格隔開。

數據範圍
1≤N,C≤1000
輸入樣例:
4
2
4
5
231
輸出樣例:
1 2 5
2 4 13
3 5 21
4 231 32549

題意可以分析得到只要橫縱座標互質就可以成爲可見點,就有暴力做法,直接枚舉橫縱座標,再用gcd判斷是否互質,計數器加加就可以了,但是這樣的做法n^2複雜度,配上多組輸入的話就是 cn方複雜度。就過不了。這裏想到求質數也可以用歐拉函數,sqrt(n)複雜度,降低所用時間。這裏,求出某個數比它小的所有質數後(s),就可以與它組成2s個座標,而這些座標都可以可見,這裏,(0,1),(1,0)(1,1)三個點要分開討論,直接在最後結果加3就可以了,其他的枚舉算出質數後加它的兩倍即可。
c++代碼如下:

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;

const int INF = 0x3f3f3f3f;
const double eps = 1e-5;
const int mod = 1e9+7;
const int N = 1010;

//歐拉函數求質數
int phin(int n)
{
	int res = n;
	for(int i=2;i<=n/i;i++)
		if(n%i==0)
		{
			res = res/i*(i-1);
			while(n%i == 0) n/=i;
		}
	if(n > 1) res = res/n * (n-1);
	return res;
}

int main(){
	int n;scanf("%d",&n);
	
	for(int i=1;i<=n;i++)
	{
		int a;scanf("%d",&a);
		
		ll con = 0;
		//枚舉求質數
		for(int i=2;i<=a;i++)  con+=phin(i);

		printf("%d %d %lld\n",i,a,2*con + 3);
	}
	
	return 0;
}

python 3 代碼(纔開始學py):

def phin(x):
    res = x
    i = 2
    while i <= x//i:
        if x%i == 0:
            res = res//i *(i-1)
            while x%i == 0:
                x//=i
        i+=1
    if x > 1:
        res = res//x *(x-1)
    return res


n = int(input())

for j in range(1,n+1):
    a = int(input())
    con = 0
    for i in range(2,a+1):
        con += phin(i)

    print("{:d} {:d} {:d}".format(j,a,2*con+3))

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