標籤:
第一部分:題目
生物晶片
X博士正在研究一種生物晶片,其邏輯密集度、容量都遠遠高於普通的半導體晶片。
博士在晶片中設計了 n 個微型光源,每個光源操作一次就會改變其狀態,即:點亮轉為關閉,或關閉轉為點亮。
這些光源的編號從 1 到 n,開始的時候所有光源都是關閉的。
博士計劃在晶片上執行如下動作:
所有編號為2的倍數的光源操作一次,也就是把 2 4 6 8 ... 等序號光源開啟
所有編號為3的倍數的光源操作一次, 也就是對 3 6 9 ... 等序號光源操作,注意此時6號光源又關閉了。
所有編號為4的倍數的光源操作一次。
.....
直到編號為 n 的倍數的光源操作一次。
X博士想知道:經過這些操作後,某個區間中的哪些光源是點亮的。
【輸入格式】
3個用空格分開的整數:N L R (L<R<N<10^15) N表示光源數,L表示區間的左邊界,R表示區間的右邊界。
【輸出格式】
輸出1個整數,表示經過所有操作後,[L,R] 區間中有多少個光源是點亮的。
例如:
輸入:
5 2 3
程式應該輸出:
2
再例如:
輸入:
10 3 6
程式應該輸出:
3
資源約定:
峰值記憶體消耗 < 256M
CPU消耗 < 1000ms
請嚴格按要求輸出,不要畫蛇添足地列印類似:“請您輸入...” 的多餘內容。
所有代碼放在同一個源檔案中,調試通過後,拷貝提交該源碼。
注意: main函數需要返回0
注意: 只使用ANSI C/ANSI C++ 標準,不要調用依賴於編譯環境或作業系統的特殊函數。
注意: 所有依賴的函數必須明確地在源檔案中 #include <xxx>, 不能通過工程設定而省略常用標頭檔。
提交時,注意選擇所期望的編譯器類型。
第二部分:思路
本來我是按照原始方法寫的。從L~R對2~ n進行計算,如果因子數為奇數那麼該光源就是關閉的,因為是從2開始計算的,而1是所有數的一個因子,所以因子數為奇數的都關閉了。這種方法結果很明顯,逾時。然後看了網上的討論。得知因子數為奇數的數叫做完全平方數,完全平方數就是能夠寫成m*m的形式的數,它其中一個特點就是因子數是奇數個。但是資料是10的15次方,如果一個個判斷還是逾時,怎麼辦呢?聲明一個變數 i 從 L 的算術平方根開始枚舉,直到 i*i 大於R。只要i*i在[L,R]範圍內,那麼說明編號為 i*i 的光源是關閉的。定義sum=R-L+1,表示區間內光源總數,每當光源是關閉的就減一。
第三部分:代碼
#include<stdio.h>#include<stdlib.h>#include<math.h>int main(){ int n; long long a,b,len=0;//因為資料比較大,定義為long long 型 scanf("%lld%lld%lld",&n,&a,&b); long long sum; sum=b-a+1;//區間中光源總數 for(long long i=sqrt(a);i*i<=b;i++) { if(i*i>=a&&i*i<=b) { sum--;//關閉的光源減去 } } printf("%lld\n",sum); return 0;}
第五屆藍橋杯決賽C\C++B組——生物晶片