Best Cow Line( 最佳奶牛系列)

本文探讨了一种算法,用于解决给定一个字符序列,如何通过每次只能取序列首或尾形成新字符串的问题,目标是使新字符串的字典序最小。文章详细介绍了算法的实现思路,采用贪心策略,并提供了C语言的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门

 数据:

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 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

一般样例容易过,做题还得自己多找找特殊样例,   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加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵩韵儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值