数据:
Input
* Line 1: A single integer: N N<=2000
* Lines 2..N+1: Line i+1 contains a single initial ('A'..'Z') of the cow in the i th position in the original lineOutput
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 BSample Output
ABCBCD一般样例容易过,做题还得自己多找找特殊样例, 6 ABCCBA output AABBCC (完全对称,头尾相等)
题意:(原文核心)(翻译)
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.
他通过重复地将原始行(剩余部分)中的第一只或最后一只奶牛发送到新行的末尾,将奶牛从旧行编组到新行。当他完成后,FJ把他的奶牛登记在这个新的顺序。给定他的奶牛的最初顺序,确定他能以这种方式制作的最少的字典顺序的首字母串。
题意: 一个为n的字符序列,通过每次只能取首或者尾,形成一个新的字符串,要求字典序最小;
思路:贪心策略,每次比较首尾,取字典序最小的(当下最优状态),如果相等就缩小搜索范围,首++,尾- -,直到找到不相等的(若首小,则输出首<最初相等的那个首,不是经过缩小范围后的首,这里注意一下,不太好描述>,自己动手模拟一下题中给的样例就清楚了~),或者不满足条件的... 见代码!
CODE:
code注释的也是比较详细了,emmm....就是,从这个题中也get到有新的点,比如字符循环输入的方式,getchar()...
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long ll;
const int N=1e5+10;
char a[2020],b[2020];
///a[]是原来字符顺序,b[]是排序后的顺序
int main()
{
int n;
while(~scanf("%d",&n))///可以多组输入,也可以只输入一组
{
for(int i=1;i<=n;i++)///从1~n
{
getchar();///先吸收回车符 再输入 这样方便
scanf("%c",&a[i]);
}
int l=1,r=n;///left左 right右 代替一串字符的头和尾
int k=1;///k变量是控制b数组存储的顺序变量
while(l<=r)///约束条件
{
if(a[l]<a[r])///左小 取左 然后左边变量就++,意思就是后移一位
{
b[k++]=a[l];
l++;
}
else if(a[l]>a[r])///右小。。同理
{
b[k++]=a[r];
r--;
}
else///头尾相等 开始压缩范围
{
int i=l,j=r;///临时变量,因为缩小范围时,会改变变量值
while(i<=j&&a[i]==a[j])///压缩范围,直到找到不相等的或者是i<=j不满足,就是字符串搜索完了,跳出循环
i++,j--;///左(向右移动一位)右(向左移动一位)
if(a[i]<=a[j])///缩小范围后找到的小于(取头)或者等于(可以取头,也可以取尾,不会影响结果)!!
{
b[k++]=a[l];
l++;
}
else///取尾
{
b[k++]=a[r];
r--;
}
}
}
for(int i=1;i<k;i++)///注意从1开始输出,因为k的初值为1
{
printf("%c",b[i]);
if(i%80==0)printf("\n");///满80个字符就换行
}
printf("\n");
}
return 0;
}
还在奋斗的Acmer加油!