213. 字典序最小问题 Best Cow Line(挑战程序设计竞赛)

地址 https://www.papamelon.com/problem/213

给定一个字符 S,长度为 N。由 S 构成出新的字符串 T,长度也为 N。

起初 T 是一个空串,然后执行 N 次操作,每次操作有两种选择:

从 S 头部删除一个字符,加到 T 的尾部
从 S 尾部删除一个字符,加到 T 的尾部
我们要决定一种最优的操作方案,使得 T 串的字典序最小。

输入
第一行整数 N(1≤N≤2000),表示 S 串的长度
接下来 N 行,每行一个大写英文字符,表示 S 串的每个字符
输出
输出一行或多行:每行最多 80 个字符,当 T 串太长,需要换行再继续输出
样例 1
输入
6
A
C
D
B
C
B
输出
ABCBCD

解答
贪心算法
从字符串S中左右两端取出字典序较小的那个 放入T中 比如 s= acdb 那么最后 t=abcd
需要考虑的特殊情况就是 两边都相同的情况下 s= abccccba,那么需要左右双指针同时向中间移动监测,直到某一边出现了字典序较小的结果,或者两端相遇 那就随机选择

// 11111.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <string>

using  namespace std;

const int N = 2010;
char S[N]; 
int n;

int Check(int l, int r) {
	int ret = -1;
	int ll = l; int rr = r;
	while (ll < rr) {
		if (S[ll] > S[rr]) { ret = r; break; }
		else if (S[ll] < S[rr]) { ret = l; break; }
		else {
			ll++; rr--;
		}
	}
	if (ret == -1) ret = l;
	return ret;
}

int main()
{
	
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> S[i];
	}
	int l = 0; int r = n - 1;
	string ans;
	while (l <= r) {
		if (S[l] > S[r]) { ans += S[r]; r--; }
		else if (S[l] < S[r]) { ans += S[l], l++; }
		else {
			//s[l]==s[r]
			int idx = Check(l,r);
			ans += S[idx];
			if (idx == l)l++;
			else r--;
		}
	}

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

	return 0;
}

我的视频题解空间

posted on 2023-01-02 12:30  itdef  阅读(33)  评论(0编辑  收藏  举报

导航