參考:
題目:
你是乙個掛科選手。
你現在正在考試,你很方。
你參加的考試叫做智商杯考試。
這個考試很奇怪,考試一開始就把所有答案全部發給你了,但是並不告訴你答案和考試題目的對應關係,也就是說你根本不知道這個答案是哪個題目的。
由於智商低的原因,你根本看不懂題目,所以從題目來推斷答案究竟屬於哪個題目是不可能的……
但是別慌,你可以向監考老師提問嘛。
智商杯的監考老師可是很人道的哦。
他允許你一次性最多問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...