POJ 3617——Best Cow Line(贪心)

链接:http://poj.org/problem?id=3617

 

题解

#include<iostream>
using namespace std;

const int MAX_N=2e3+50;
int N; //输入字符串的字符个数
int count; //记录字符个数,满足换行要求 
char S[MAX_N]; //存放字符串的数组 
void solve(){
	int a=0,b=N-1;
	
	//剩余的字符串起于 S[a],止于 S[b]
	while(a<=b){ //若不取等,最终会剩余一个字符 
		//将从左起和从右起的字符进行比较
		bool left=false;
		
		for(int i=0;a+i<=b;++i){ //注意这个循环,避免了 if语句无法解决的两侧有好几个相同字符的问题,比如 ACCDBCCB
			if(S[a+i]<S[b-i]){
				left=true;
				break;
			}
			if(S[a+i]>S[b-i]){
				left=false;
				break;
			}
		}
		if(left) printf("%c",S[a++]); //注意 a++和下面的 b--用法
		else printf("%c",S[b--]);
		
		count++; //除了最后一行,每一行只包含80个大写字母。因为这个问题,PE了好多次,悲痛
		if(count==80){
			printf("\n");
			count=0;
		}
	}
	printf("\n");
}

int main(){
	while(~scanf("%d",&N)){
		for(int i=0;i<N;++i){
			scanf(" %c",&S[i]);
		}
		solve();	
	}
	return 0;
}

为了构造字典序尽可能小的字符串,越靠前的字符 ASCII值越小。所以不断取 S开头和末尾的字符进行比较,选择更小的输出

但要注意,S开头和末尾的字符相同的情况较为复杂,不清楚它们内侧字符的大小。如果用 if 语句判断,又无法解决多个相同字符的情况(总不能一直嵌套的判断下去),这时循环语句就能取得很好的效果(题解中的 for 循环)

字典序比较类的问题经常能用贪心算法

 

与诸君共勉 ^_^

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值