P1277 智商杯考試

2021-09-01 17:41:43 字數 2284 閱讀 7323

參考:

題目:

你是乙個掛科選手。

你現在正在考試,你很方。

你參加的考試叫做智商杯考試。

這個考試很奇怪,考試一開始就把所有答案全部發給你了,但是並不告訴你答案和考試題目的對應關係,也就是說你根本不知道這個答案是哪個題目的。

由於智商低的原因,你根本看不懂題目,所以從題目來推斷答案究竟屬於哪個題目是不可能的……

但是別慌,你可以向監考老師提問嘛。

智商杯的監考老師可是很人道的哦。

他允許你一次性最多問m個答案的對應關係,他會告訴你這m個答案對應哪m道題,當然,他不會告訴你具體的對應關係。 比如:

你可以問:1,2,3號答案對應哪些問題?

監考老師說:對應3,7,9號問題。

假設你比較蛋疼,你問:1,1,2,3號對應哪些問題?

監考老師說:對應3,7,9號問題。

現在問題來了,考試一共有n道問題,你每次提問最多提及m個答案,你需要最少問多少次呢?

兩個整數,1<=n,m<=1e9。

輸出乙個整數,表示最少詢問次數。

input

output

4 2
2

7 3
3

15 4
6

樣例解釋:

你:1,2號答案對應哪些題目呢?

監考老師:對應3,4號題目。

你:1,3號答案對應哪些題目呢?

監考老師:對應2,4號題目。

你想了想:由於我問了兩遍,都出現了4,所以4號題目肯定對應1號答案;再從第乙個詢問中得知,3號題目對應2號答案;第二個詢問知道,2號題目對應3號答案;哦,那麼剩下的4號答案就對應1號題目了!

這樣,你就智商得到了昇華。

完美。by qscqesze

problem id

1277

time limit

1000 ms

memory limit

64 mib

output limit

64 mib

source

每週一題 div2

題解:

需要了解的重要一點。我們要求的是至少詢問幾個問題能得到這些答案。

利用二進位制表示答案的種數(類似於餵藥喂幾隻小白鼠判斷毒藥)。

假設有n個藥,把藥變為二進位制,10=1010,表示餵給第一只小白鼠和第三隻小白鼠。從而可以單獨判斷出這個藥。

10只小白鼠可以判斷出1024種藥。

這裡同理,每道題用二進位制表示從而可以單獨判斷,位置上為1表示要問這個問題。只需要二分答案ans,通過得到滿足的k再判斷最少用多少1,並且比較一下1會不會超過k*m.

我們已經知道的是每一列也就是1個問題不能超過m,假設存在1的個數等於k*m,但有一列超過m了。

我們得到1的總數很簡單。先從c(k,0)開始,c(k,1)貪心加1上去,能保證最小,如果取到c(k,i),並且只取中間一部分。

比如c(4,2):必然先取0011,1100保證每一列最多加1,但是c(4,3)0111 1110有兩位會多加上1,但是之後肯定會通過1101,1011保證每一步每一列1的差距最多是1。如果有一列大於m,必然有一列小於m。假設乙個是m+1,乙個就是m-1.這個差距是不可能達到。所以簡單的判斷和k*m的大小比較即可。

#includeusing namespace std;

#define rep(a,b) for(int i=a;i<=b;i++)

#define red(a,b) for(int i=a;i>=b;i--)

#define ull unsigned long long

#define ll long long

ll pow(int base,int r)

r>>=1;

base*=base;

}return ans;

}ll n,m;

int check(long long k)//檢驗k個問題能否滿足出現n個二進位制數,滿足的話能否限制每一列的和都小於等於m

}int main()

cout

}

P1968 美元匯率 懷疑智商超過海平面

也是一道貪心題,一些計算 然而我卻弄得很複雜 既然我們要的是最後的最大值,那我們為什麼要注意中間的細節呢 記錄每天我們能拿到的最大值,然後輸出,完美結束 include include include using namespace std const int maxn 200 int n doub...