E. The Cake Is a Lie
題目大意
D. Enchanted Artifact (1s 256Mb)
題目大意
交互題。一臺機器有一個僅由a和b組成的字符串,當你輸出這個字符串時,這臺機器就會被摧毀,否則他會輸出他的字符串和你輸出的字符串的編輯距離(好東西,可以研究一些)。你最多輸出 次去摧毀他。他的字符串長度不超過300,除此之外你啥都不知道。
分析
比賽時候在這自閉了半個多小時,考慮怎麼去先得到字符串長度,再去判斷每一位。事實證明這種構造神題不是我短時間內能解決的。以下用 表示讀到的數。
先輸出300個a,a的個數就是 ,因爲距離是 刪去的個數 + b的個數(改成a)。同理求得b的個數。得到字符串長度
輸出任意一個 長的字符串,得到 設爲 。將每一位翻轉輸出,如果得到的(應該是),那麼翻轉後的是正確的,否則翻轉前的是正確的。最後輸出正確字符串
這樣我們用次完成任務。觀察思考發現,設任意字符串爲全a,則不用輸出便知是b的個數。同時最後一位不用翻轉,通過a和b的個數即可推理得到,這樣我們只用次即可摧毀機器。
代碼
int main()
{
for(int i = 1; i <= 300; i++) putchar('a');
putchar(10); fflush(stdout);
qa = 300-read(); if(qa == 300) return 0;
for(int i = 1; i <= 300; i++) putchar('b');
putchar(10); fflush(stdout);
qb = 300-read(); if(qb == 300) return 0; //qa是a的個數 qb是b的個數
n = qa+qb;
for(int i = 1; i <= n; i++) s[i] = 'a'; s[n+1] = '\0';
int cnta = 0, d = qb;
for(int i = 1; i < n; i++)
{
s[i] = 'b'; printf("%s\n", s+1); fflush(stdout);
int u = read(); if(u == 0) return 0;
if(u < d) ans[i] = 'b';
else ans[i] = 'a', cnta++;
s[i] = 'a';
}
ans[n] = cnta < qa ? 'a' : 'b'; //推斷最後一位
printf("%s\n", ans+1);
return 0;
}
B. K for the Price of One (Easy/Hard Version) (2s 256Mb)
題目大意
(2e5) 個貨物,每個有價錢 (1e4),你有(2e9)的錢,可以直接一個一個買;如果一氣買 個,只需要付最貴的那個的錢,求最多可以買多少個。
分析
一道不錯的貪心題,自己比賽時用 方法做的,但爆了int了。
我覺得應該從答案特點分析,想辦法尋找時覆蓋答案比較好。考慮答案,顯然貪心考慮應該是最便宜的。同時肯定儘量用優惠規則,這樣剩下單個買的只能是不到 個,即 的餘數。而使用優惠的方法肯定是用最貴的(不能被免費掉)去免費掉剩下最貴的,單個買的就是最便宜的那幾個。這樣我們只要枚舉單個買的個數,在往後隔 個枚舉能買的個數乘 ,由於每個數字只被枚舉到一次,故可以在線性時間內解決,不過排序部分還是 的。
評論裏有人說桶排,這題數據組數T到了1e4,不值。
代碼
int main()
{
int T = read(); while(T--)
{
n = read(); m = read(); k = read();
for(int i = 1; i <= n; i++) a[i] = read();
sort(a+1, a+n+1);
for(int i = 1; i <= n; i++) pre[i] = pre[i-1]+a[i];
int ans = 0;
for(int sta = 0; sta < k; sta++) //單個買的個數
{
if(m < pre[sta]) break;
int anss = sta, y = m-pre[sta];
for(int i = sta+k; i <= n; i += k) //隔k枚舉
{
if(a[i] > y) break;
y -= a[i];
anss += k;
}
ans = max(ans, anss);
}
printf("%d\n", ans);
}
return 0;
}