poj3617 Best Cow Line 贪心

第一次用md格式,可能打出来比较丑:)
先说一下题意:给你长度为N的字符串S。可以取当前字符串首位/最末位的字符放在新的字符串,求进行N次操作后字典序最小的新字符串
解释一下样例:

Input:
6
ACDBCB

首位是A,末位是B,显然字典序:A < B,所以目前的新字符串就是

A

现在首位是C,末位是B,显然字典序:B < C,所以目前的新字符串就是

AB

以此类推,答案就是

Output:
ABCBCD

这个题贪心意图也挺明显的。一开始拿到这道题还想的是暴力的取最前/最后的字符然分别放入新串中用strcmp做,但1s时间肯定不够用。书上的方法就很巧妙了:)。
因为题意的特点可以看出,对于S的反转串S’求出的答案和用S求出的答案是一样的,所以就可以先构造串S的反转S’,再通过strcmp决定是用S的首位或是S’的首位(即S的末位)。以此类推直到S被删空。
题目中 N<=2000 ,所附的代码平均情况在规定时间内完全可以实现,代码如下↓

#include <stdio.h>
#include <string.h>
#define MaxN 2100
int n, cnt, len;
char str1[MaxN], str2[MaxN], ans[MaxN];
int main() {
    scanf("%d\n", &n);
    for (int i = 1; i <= n; i++) {
        str1[i] = getchar();
        getchar();
        str2[n - i + 1] = str1[i];
    }
    str1[0] = str2[0] = '0';
    for (int T = 1; T <= n; T++) {
        if (strcmp(str1, str2) >= 0) {
            ans[++cnt] = str2[1];
            len = strlen(str2);
            for (int i = 1; i <= len; i++)
                str2[i] = str2[i + 1];
            str2[strlen(str2)] = '\0';
            str1[strlen(str1) - 1] = '\0';
        }
        else if (strcmp(str1, str2) < 0) {
            ans[++cnt] = str1[1];
            len = strlen(str1);
            for (int i = 1; i <= len; i++)
                str1[i] = str1[i + 1];
            str2[strlen(str2) - 1] = '\0';
            str1[strlen(str1)] = '\0';
        }
    }
    for (int i = 1; i <= n; i++) {
        printf("%c", ans[i]);
        if (i % 80 == 0)
            printf("\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值