poj3617:Best Cow Line

题目描述

给定一个长度为n的字符串s,将s重排得到字符串t,使得字符串t的字典序最小,且只能使用下面两种操作

  • 从s的头部取一个字符放在t末尾
  • 从s的尾部取一个字符放在t末尾

分析

贪心策略

最直接的想法,比较s的头部字符和尾部字符,将较小的插入到t末尾。

但存在一个问题,当s头部字符和尾部字符相同时,就要比较头部第二个字符和尾部第二个字符,此时仍会出现同样的问题,就要一直比较下去...

基于上面的分析,每次插入时,比较s和其逆序s1的字典序大小,若s字典序较小,则选择s头部字符插入,反之则选择s尾部字符插入,若s和s1字典序也相同,选择头部尾部均可

代码

#include<stdio.h>
#include<iostream>
using namespace std;

const int MAXN = 3000;	//注意数组大小
char s[MAXN], t[MAXN];

/**
 * 判断s[left]-s[right]正序和反序的字典序大小
 * @param left
 * @param right
 * @return true:正序小于反序,从left取元素
 */
bool Judge(int n, int left, int right){
    for(int i = left, j = right; i < n, j >= 0; ++i, --j){
        if(s[i] < s[j]){
            return true;
        }
        else if(s[i] > s[j]){
            return false;
        }
    }
    return true;
}

int main(){
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; ++i){
        getchar();
        scanf("%c", &s[i]);
    }
    int k = 0;
    int left = 0;
    int right = n - 1;
    while(k < n){
        if(Judge(n, left, right)){  //从left取
            t[k++] = s[left++];
        }
        else{
            t[k++] = s[right--];
        }
    }
    int cnt = 0;
    for(int i = 0; i < k; ++i){
        putchar(t[i]);
        ++cnt;
        if(cnt == 80){		//处理输出,每80个字符一行
            putchar('\n');
            cnt = 0;
        }
    }
    putchar('\n');

    return 0;
}

posted @ 2022-02-13 17:56  dctwan  阅读(36)  评论(0编辑  收藏  举报