對於乙個正整數x,如果把x化成二進位制數後,如果x的二進位制數至少有三個連續的1或者至少有3個連續的0(不能有前導0),那麼x就是「好數」。例如8就是「好數」,因為8對應的二進位制數是1000,有三個連續的0。整數15也是「好數」,因為15對應的二進位制數是1111,也有三個連續的1。整數27就不是「好數」,因為27對應的二進位制數是11011,既沒有連續的三個1也沒有連續三個0。
現在給出兩個整數low、up,求low和up範圍內有多少個「好數」。
input
一行,兩個整數low、up,其中0 <= low <= up <= 2147483647。
output
乙個整數。
sample input
0 16
sample output
是數字dp。之前有接觸到,但是比賽的時候就是想不起來有這種玩意。。。
(最終還是k了一下別人的**。。。lyftql)(沒辦法現在的我覺得那是最優打法)
我們可以知道,沒有三個同樣的數連在一起的數為「壞數」,那麼「好數」=總數-「壞數」。
設f[i][x=0/1][y=0/1]為:第i位為x,第i-1位為y的壞數總數。
使三個數不同,得:
f[i][0
][0]
=f[i-1]
[0][
1];f[i][0
][1]
=f[i-1]
[1][
0]+f[i-1]
[1][
1];f[i][1
][0]
=f[i-1]
[0][
1]+f[i-1]
[0][
0];f[i][1
][1]
=f[i-1]
[1][
0];
這樣就可以算出1-1,10-11,100-111,1000-1111…的「壞數」了。
然後從高位列舉1變成0,注意使它與前面的不形成3個0。然後如果它已經連成三個了,後面再變就沒必要了,-1,退出。
然後以下**推了一下90分,瓦不管了。。。。(心累,注釋也暫時不想打了)
#include
#include
using
namespace std;
int f[
101][3
][3]
,s[101
],l,r,kl,l1,l2,ans,t;
intc
(int k)
if(t==
0) l2=w;
else l1=w;
t=1;
int ans=1;
for(
int i=w-
1;i;
--i)
}return ans;
}int
main()
ans=r-l+1-
c(r)+c
(l-1);
for(
int i=l1;i++i)
kl=kl+f[i][1
][0]
+f[i][1
][1]
; ans-
=kl;
printf
("%d"
,ans)
;fclose
(stdin);
fclose
(stdout);
}
NOIP模擬賽 好數
題解,這道題呢一看資料就很小,很輕鬆就可以看出來是道水題。有兩種暴力做法,一種是先暴力打個表,把所有好數判斷出來,然後它要什麼答什麼就ok。另一種是在它問了之後再去找比它大的m個數。判斷乙個數是不是好數隻用看他轉換為三進製下的每一位是多少就行。只需要除以每乙個三的n次方就行 includeusing...
NOIP模擬 好題 分玩具
題目描述 豆豆和豆沙正在分一些玩具,每個玩具有乙個好玩值,每個人可以拿走任意數量的玩具,獲得的愉快度為最小的好玩值。現在豆豆先拿,每個人輪流操作,直到沒有玩具可以拿。豆豆想知道他能比豆沙多出多少愉快度?輸入格式 第一行 n 表示玩具個數。接下來一行 n 個整數表示第 i 個玩具的好玩值。輸出格式 輸...
搜尋 模擬好題 終焉花海
首先看要輸出任何一種解 想到搜尋或者模擬 再想搜尋順序問題,發現應倒序搜尋,每次搜尋當前最後一次覆蓋的位置 這樣的話後面的搜尋就不會對前面的覆蓋產生影響 所以每次在a串裡匹配b串,把匹配位置換成 以後搜尋過程中 可按萬能位置匹配 因為一定有解,所以當a串全部變成?就覆蓋成功了 倒序輸出搜尋答案即可 ...