1. 程式人生 > 其它 >1039 到底買不買 (20 point(s))

1039 到底買不買 (20 point(s))

#include <bits/stdc++.h>
using namespace std;

int main() {
	// 包含全部需要珠子 剩餘 或缺少
	// 跟舊鍵盤的思路類似 一個預定的輸入 一實際輸出
	map<char, int> store, red;
	string s, r;
	
	// 讀取攤主和小紅的字串 
	getline(cin, s);
	getline(cin, r);
	
	// 用map統計每個字元的個數
	for(int i = 0; i < s.size(); i++)
		store[s[i]]++; 
	for(int i = 0; i < r.size(); i++)
		red[r[i]]++; 
		
	// 統計多出或少於的(字元)數
	int more = 0, lose = 0;
	
	for(auto s: store){
		// 區分情況
		// 遍歷每一個字元 供給多於需求 (等於 算不算都一樣 都是0 
		if(s.second > red[s.first])
			more += s.second - red[s.first];
		// 找得到 但少於需求
		else 
			lose += red[s.first] - s.second;
			
		// 擦除遍歷過的需求的字元 
		red.erase(s.first);
	}
	
	// 遍歷剩餘字元 這部分必然是缺少的字元
	for(auto r: red)
		lose += r.second; 
	
	if(lose > 0)
		cout << "No " << lose;
	else
		cout << "Yes " << more; 
}

開始的時候以為跟前面舊鍵盤的思路差不多。但是寫到後面的情況發現不太對。相似的處理僅限於供給能夠滿足需求的時候,這時候兩個集合的元素 供給 ≥ 需求。

這個情況可以類比當時舊鍵盤題目的時候,當輸入經過處理使得部分缺失而得到實際輸出,也是 輸入 ≥ 輸出。

但這裡如果供給不滿足需求,意味著兩個集合的元素有一部分是沒有交叉的。比如供給有 1 2 3 需求是 2 3 4,那麼這時候 4 就遊離在兩個集合的交集之外了。這部分就是跟舊鍵盤題目不一樣的地方。

所以需要考慮對交集以外的部分進行處理,就是迴圈處理兩次,一次解決交集部分,另一次解決交集以外。


參考程式碼

參考別人的思路。可以將需求和供給的元素個數放在同一個 map 容器裡面,當讀取供給字元的時候 ++, 需求字元的時候 -- 。最後將正負不同的部分分別求和即可。

我們原本是先讀取兩個不同部分各自的元素個數,然後運算再統計。參考的思路里面,可以看到最終結果都是要運算統計的,所以就省去了儲存的步驟,直接在讀取字串時就運算。