日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

51nod 1536不一样的猜数游戏 思路:O(n)素数筛选法。同Codeforces 576A Vasya and Petya‘s Game。

發(fā)布時間:2024/4/19 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 51nod 1536不一样的猜数游戏 思路:O(n)素数筛选法。同Codeforces 576A Vasya and Petya‘s Game。 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

廢話不多說,先上題目。

?

51nod

?

?

Codeforces

?

?

?

兩個其實是一個意思,看51nod題目就講的很清楚了,題意不再贅述。

直接講我的分析過程:剛開始拿到手有點蒙蔽,看起來很難,然后。。。。。。然后我就開始一頓胡蒙,各種舉例子、找規(guī)律下面為我取n = 10的過程。

?

?

?

1.首先1肯定不用取。因為它太特殊了,如果 取它的話,只能判斷是不是1,因為所有數都是1的倍數;反之其他所有情況排除了就選它,不用浪費次數來取它。

?

2.素數肯定是要取的。因為。。。。。。因為這題一看就是考素數的題。

?

3.以10為例,如果是2,3的倍數,則為6。如果是2,5的倍數則為10。如果不是2的倍數,是5的倍數則為。如果是7的倍數則為7。現在我們根據2,3,5,7這4個素數選出了6,10,5,7這4個數。肯定還要再加數,怎么加?

?

4.如果加一個數能多判斷更多的數最好了,先考慮3,3的倍數有3、6和9,6我們用2、3組合判斷過了,3和9能怎么判斷?肯定不能不選3而選9用排除法,因為1已經用了排除法,排除法只能用一次。因為要判斷所有數字,想要判斷3和9必須要同時取3和9,這樣只多取了一個9我們就多判斷了兩個數字。現在我們能判斷6、10、5、7、3、9這6個數字了。

?

5.再看2,2的倍數有2、4、6、8、10。6和10我們已經用2、3和2、5組合判斷了,我們觀察剩余的數字還有2、4、8,我尼瑪?什么情況,如果剛剛的3和9是巧合的話,這里的2、4、8還是巧合?現在我們取中2、4、8三個數就可以判斷這3個數了。我們判斷出了9個數6、10、5、7、3、9、2、4、8,然后1用排除法,所以我們判斷出了這10個數了。

?

?

?

這里我們觀察到我們選出的都是素數的次方(小于n)。以10為例,2,4,8(2的次方);3,9(3的次方);5(5的次方);7(7的次方)。然后多試幾例,發(fā)現就是這個規(guī)律。

?

?

現在我們有兩條路可走:

  • 找出所有的素數和它的次方(小于n),順帶用一個count計數。
  • 找出所有不取的數計數count,然后用n減去這個count。即為任意找出兩個素數a、b。排除所有a的次方 乘 b的次方。什么?為什么排除它們?想一想第一條路的補集不就是它們嗎?
  • ?

    ?

    ?

    然后分析,發(fā)現第一條路只用找出素數及其次方,第二條路要在第一條路的基礎上做更多工作,所以果斷選擇第一條路。

    ?

    ?

    ?

    下面是代碼了:

    再加點注釋:

    #include <bits\stdc++.h> using namespace std;//素數篩選法 O(n) ,見那本小紅書(ACM國際大學生程序設計競賽-算法與實現) int ans[1001]; //存入所有素數。 bool valid[1001]; //判斷第i個是不是素數。 void getPrime(int n,int &tot){memset(valid,true,sizeof(valid));for(int i = 2;i <= n; i++){if(valid[i]){tot++;ans[tot] = i;}for(int j = 1;((j <= tot)&&(i*ans[j] <= n)); j++){valid[i*ans[j]] = false;if(i%ans[j] == 0) break;}} }int main(){int n;cin >> n;int res = 0; // 素數及其次方的數量 int tot = 0; // 小于等于n的素數的數量 getPrime(n,tot); //篩選出素數 for(int i = 1;i <= tot; i++){ //遍歷范圍內素數,找出其次方 int t = ans[i];while(t <= n){res++;t*= ans[i];}}cout << res << endl;return 0; }

    ?

    ?

    總結

    以上是生活随笔為你收集整理的51nod 1536不一样的猜数游戏 思路:O(n)素数筛选法。同Codeforces 576A Vasya and Petya‘s Game。的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。