Codeforces Round #610

E. The Cake Is a Lie

題目大意


D. Enchanted Artifact (1s 256Mb)

題目大意

交互題。一臺機器有一個僅由a和b組成的字符串,當你輸出這個字符串時,這臺機器就會被摧毀,否則他會輸出他的字符串和你輸出的字符串的編輯距離(好東西,可以研究一些)。你最多輸出 n+2 次去摧毀他。他的字符串長度不超過300,除此之外你啥都不知道。

分析

比賽時候在這自閉了半個多小時,考慮怎麼去先得到字符串長度,再去判斷每一位。事實證明這種構造神題不是我短時間內能解決的。以下用 q 表示讀到的數。

先輸出300個a,a的個數就是 300-q,因爲距離是 刪去的個數 + b的個數(改成a)。同理求得b的個數。得到字符串長度 n

輸出任意一個 n 長的字符串,得到 q 設爲 d 。將每一位翻轉輸出,如果得到的q<d(應該是d-1),那麼翻轉後的是正確的,否則翻轉前的是正確的。最後輸出正確字符串

這樣我們用n+4次完成任務。觀察思考發現,設任意字符串爲全a,則不用輸出便知d是b的個數。同時最後一位不用翻轉,通過a和b的個數即可推理得到,這樣我們只用n+2次即可摧毀機器。

代碼

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)

題目大意

n(2e5) 個貨物,每個有價錢 a_i(1e4),你有p(2e9)的錢,可以直接一個一個買;如果一氣買 k(2 \leq k \leq n) 個,只需要付最貴的那個的錢,求最多可以買多少個。

分析

一道不錯的貪心題,自己比賽時用 O(nlogn) 方法做的,但爆了int了。

我覺得應該從答案特點分析,想辦法尋找時覆蓋答案比較好。考慮答案,顯然貪心考慮應該是最便宜的。同時肯定儘量用優惠規則,這樣剩下單個買的只能是不到 k 個,即 k 的餘數。而使用優惠的方法肯定是用最貴的(不能被免費掉)去免費掉剩下最貴的,單個買的就是最便宜的那幾個。這樣我們只要枚舉單個買的個數,在往後隔 k 個枚舉能買的個數乘 k,由於每個數字只被枚舉到一次,故可以在線性時間內解決,不過排序部分還是 O(nlogn) 的。

評論裏有人說桶排,這題數據組數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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章