poj_3617 Best Cow Line(贪心)

题目链接

Description
FJ is about to take his N (1 ≤ N ≤ 2,000) cows to the annual"Farmer of the Year" competition. In this contest every farmer arranges his cows in a line and herds them past the judges.
The contest organizers adopted a new registration scheme this year: simply register the initial letter of every cow in the order they will appear (i.e., If FJ takes Bessie, Sylvia, and Dora in that order he just registers BSD). After the registration phase ends, every group is judged in increasing lexicographic order according to the string of the initials of the cows’ names.
FJ is very busy this year and has to hurry back to his farm, so he wants to be judged as early as possible. He decides to rearrange his cows, who have already lined up, before registering them.
FJ marks a location for a new line of the competing cows. He then proceeds to marshal the cows from the old line to the new one by repeatedly sending

either the first or last cow in the (remainder of the) original line to the end of the

new line. When he’s finished, FJ takes his cows for registration in this new order.
Given the initial order of his cows, determine the least lexicographic string of initials he can make this way.
Input
Line 1: A single integer: N
Lines 2…N+1: Line i+1 contains a single initial (‘A’…‘Z’) of the cow in the ith position in the original line
Output
The least lexicographic string he can make. Every line (except perhaps the last one) contains the initials of 80 cows (‘A’…‘Z’) in the new line.
Sample Input
6
A
C
D
B
C
B
Sample Output
ABCBCD

解题思路:本题目即为求解具有最小字典序的字符串,目标主要是从已知的字符串构造出字典序尽可能小的字符串,每次从原字符串的开头或结尾选取字符,本题中需要注意在比较过程中,如果碰到了S前面的字符和后面的字符相等的情况,则应该比较这两个字符的下一个字符(对于结尾而言则是前一个字符)。
例1:ACDBCB
先选A,然后是结尾处的B,此时剩余CDBC,开头与结尾相同,则比较D与B。B较小,因此选择后面的C(这样的原因是选中后面的C后,较小的字符B便“显露”了出来,而不是较大的D)
例2:ACDDCB
本例中会遇到C与C、D与D比较的情况(CDDC),不过没关系,继续比较相对而言的“下一个”,此时会再次经历一波结果相同的比较。由于这种情况下,剩余的字符串已经构成回文,因此从哪一侧选取都可以。本例中使用了最近的一次得出大小的比较结果,字符总数为奇数时的情况也是这样(ACDCB)。
例3:ABCCBA
本例为回文串,同样按照例2的思路来考虑,不过这时候就没有最近的一次得出大小的比较结果了,此时需要自己指定选取方向,还要注意防止数组越界(本题采用的一个flag标志来单独判断是否为回文串)。

#include<iostream>
#include<string>
#include<cstring>
#include<string.h>
using namespace std;

char a[2001];
int main() {
	string ans = "";
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	int len = n;
	int i = 1;
	int flag;//用于判断是否为回文字符串
	while (i <= len) {
		flag = 0;
		if (a[i] < a[len]) {
			ans += a[i++];
		}
		else if(a[i] > a[len]){
			ans += a[len--];
		}
		else {
			int ii = i;
			int l = len;
			while (ii<=n && l>0 && a[ii] == a[l] ) {
				if (a[ii + 1] > a[l - 1]) {
					ans += a[len--];
					flag = 1;
					break;
				}
				else if (a[ii + 1] < a[l - 1]) {
					ans += a[i++];
					flag = 1;
					break;
				}
				ii += 1;
				l -= 1;
			}
			if (flag == 0) {
				ans += a[len--];
			}
		}
	}
	int time = ans.length();
	for (int i = 0; i < time; i++) {
		cout << ans[i];
		if (i % 80 == 79) {
			cout << endl;
		}
	}
	//system("pause");
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值