题解 P2870 【[USACO07DEC]最佳牛线,黄金Best Cow Line, Gold】
这道题目其实很简单,就是贪心!!!
贪心过程: 假设 l为只想最左边的数,r为指向最右边的数,从两边比较。
若a[ l ]<a[ r ];l++; 若a[ r ]>a[ l ];r--;
若a[ l ]==a[ r ];则check:
做一次循环,l每次加1,r每次减1; 若a[ l ]<a[ r ] return 1;
否则 return 0;
还有一种玄学,就是设一个flag记录不同的字母的个数01,如果flag为1,直接输出!!!
CODE:
#include<bits/stdc++.h>
using namespace std;
int n,l,r,t=0;
bool b[30001];
char a[30001],ans[30001];
inline bool check(int l,int r){
int j=r-1;
for(register int i=l+1;i<=r;i++){
int x=a[i],y=a[j];
if(x<y) return 1;
if(y<x) return 0;
j--;
}
}
inline int read(){
int ret=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-f;ch=getchar();}
while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
int main(){
scanf("%d",&n);
int flag=-1;
for(register int i=1;i<=n;i++){
a[i]=getchar();
while(a[i]<'A'||a[i]>'Z') a[i]=getchar();
if(!b[a[i]]) b[a[i]]=1,flag++;
}
if(flag==1){
for(register int i=1;i<=n;i++){
putchar(a[i]);
if(i%80==0)putchar('\n');
}
return 0;
}
l=1;r=n;
while(l<=r){
int x=a[l],y=a[r];
if(x<y) ans[++t]=x,l++;
if(x>y) ans[++t]=y,r--;
if(x==y){
if(check(l,r)==1) l++,ans[++t]=x;
else r--,ans[++t]=y;
}
}
for(register int i=1;i<=n;i++){
putchar(ans[i]);
if(i%80==0) putchar('\n');
}
return 0;
}
码风奇丑,请多指教!!!