挑战程序设计竞赛 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;
}

posted on 2024-05-18 10:56  itdef  阅读(16)  评论(0编辑  收藏  举报

导航