挑戰程序設計競賽 2.2章習題 POJ - 3617 Best Cow Line 貪心

FJ正準備帶着他的N頭奶牛(1 ≤ N ≤ 2,000)參加一年一度的“年度最佳農民”比賽。在這個比賽中,每個農民都會將他的奶牛排成一行,然後引導它們經過評委。

今年比賽的組織者採用了一種新的註冊方案:只需按照它們出現的順序註冊每頭奶牛的首字母(即如果FJ帶着Bessie、Sylvia和Dora依次出場,他只需註冊BSD)。
註冊階段結束後,每個小組將按照奶牛名字首字母的字符串按遞增的字典順序進行評判。

FJ今年非常忙,必須趕回農場,所以他希望儘快接受評判。他決定在註冊之前重新排列已經排好隊的奶牛。

FJ標記了一個新的競爭奶牛排隊位置。然後,他開始將奶牛從舊隊列中依次發送到新隊列的末尾,每次可以選擇發送原隊列中的第一頭或最後一頭奶牛(剩餘的)到新隊列的末尾。
完成後,FJ按照這個新順序帶着他的奶牛進行註冊。

給定他的奶牛的初始順序,確定他可以通過這種方式製作的最小字典順序字符串。

輸入
* 第1行:一個整數:N
* 第2行到第N+1行:第i+1行包含原始隊列中第i頭奶牛的單個首字母('A'..'Z')

輸出
他可以製作的最小字典順序字符串。每行(最後一行除外)包含新隊列中的80頭奶牛的首字母('A'..'Z')。

6
A
C
D
B
C
B


ABCBCD

貪心解法
主要注意左右兩邊優先選擇字典序優先的字母 如果兩段字母相同 那麼就考慮下一層的字母

#include <iostream>
#include <string>

using namespace std;

const int N = 2010;
char str[N];
int n;
string ans;
int l, r;

void solveInner() {
	if (l == r) {
		ans.push_back(str[l]); l++; return;
	}
	int cpl = l; int cpr = r;
	while (cpl < cpr && str[cpl] == str[cpr]) {
		cpl++; cpr--;
	}
	if (cpl >= cpr || str[cpl] < str[cpr]) {
		ans.push_back(str[l]); l++; return;
	}
	else if (str[cpr] < str[cpl]) {
		ans.push_back(str[r]); r--; return;
	}
}

void solve() {
	l = 1; r = n;
	while (l <= r) {
		if (str[l] < str[r]) {
			ans.push_back(str[l]); l++;
		}
		else if (str[r] < str[l]) {
			ans.push_back(str[r]); r--;
		}
		else {
			solveInner();
		}
	}

	for (int i = 0; i < ans.size(); i++) {
		if (i != 0 && i % 80 == 0) {
			cout << endl;  
		}
		cout << ans[i];
	}
}


int main()
{
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> str[i];
	}

	solve();

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