POJ 3617 - Best Cow Line(字典序最小) 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。

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

洛谷题目链接:https://www.luogu.org/problem/show?pid=2870

题目大意:

给定一个长度为N(1<=N<=30000)的字母序列,每次可以从序列头部或尾部取出一个字母加入一个队列的尾部,求此队列字典序最小的排列。

每输出80个字母,换行一次。

分析:

每次比较序列首部和尾部,取出较小的一个,如果相等就继续往下比较,直到大小出现差异或者比较变量相遇。

POJ的AC代码(洛谷数据太强,改了半天不是TLE就是WA,求大神找错)

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4
  5 char def[50005],line[50005];
  6 int head,tail,n,tot = 0;
  7 inline void op(int x)
  8 {
  9     if(x == 0)
 10     {
 11         while(head <= tail)
 12             line[++ tot] = def[head ++],line[++ tot] = def[tail --];
 13         return;
 14     }
 15     else if(x == 1)
 16     {
 17         if(def[head] == def[tail])
 18             line[++ tot] = def[head ++];
 19         else if(def[head] < def[tail])
 20         {
 21             line[++ tot] = def[head ++];
 22             return;
 23         }
 24         else if(def[tail] < def[head])
 25         {
 26             line[++ tot] = def[tail --];
 27             return;
 28         }
 29     }
 30     else if(x == 2)
 31     {
 32         if(def[head] == def[tail])
 33             line[++ tot] = def[tail --];
 34         else if(def[head] < def[tail])
 35         {
 36             line[++ tot] = def[head ++];
 37             return;
 38         }
 39         else if(def[tail] < def[head])
 40         {
 41             line[++ tot] = def[tail --];
 42             return;
 43         }
 44     }
 45
 46 }
 47
 48 void solve(int l,int r)
 49 {
 50     for(int i = 1;;++ i)
 51     {
 52         if(l >= r)
 53         {
 54             op(0);
 55             break;
 56         }
 57         if(def[l] == def[r])
 58         {
 59             l++,r--;
 60             continue;
 61         }
 62         if(def[l] < def[r])
 63         {
 64             op(1);
 65             break;
 66         }
 67         if(def[r] < def[l])
 68         {
 69             op(2);
 70             break;
 71         }
 72     }
 73 }
 74
 75 int main()
 76 {
 77     char x;
 78     scanf("%d",&n);
 79     x = getchar();
 80     for(int i = 1;i <= n;++ i)
 81     {
 82         while(x < ‘A‘) x = getchar();
 83         def[i] = x,x = getchar();
 84     }
 85     head = 1,tail = n;
 86     while(head <= tail && tot <= n)
 87     {
 88         if(def[head] < def[tail])
 89             line[++ tot] = def[head ++];
 90         else if(def[tail] < def[head])
 91             line[++ tot] = def[tail --];
 92         else
 93             solve(head,tail);
 94     }
 95     for(int i = 1;i <= n;++ i)
 96     {
 97         putchar(line[i]);
 98         if(i%80 == 0)
 99             putchar(‘\n‘);
100     }
101     return 0;
102 }
时间: 2024-09-29 09:36:17

POJ 3617 - Best Cow Line(字典序最小) 题解的相关文章

poj 3617 Best Cow Line (字符串反转贪心算法)

Best Cow Line Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9284   Accepted: 2826 Description FJ is about to take his N (1 ≤ N ≤ 2,000) cows to the annual"Farmer of the Year" competition. In this contest every farmer arranges his

poj 3617 Best Cow Line

Best Cow Line Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20226   Accepted: 5563 Description FJ is about to take his N (1 ≤ N ≤ 2,000) cows to the annual"Farmer of the Year" competition. In this contest every farmer arranges his

POJ 3617 Best Cow Line (贪心)

Best Cow Line Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11230   Accepted: 3329 Description FJ is about to take his N (1 ≤ N ≤ 2,000) cows to the annual"Farmer of the Year" competition. In this contest every farmer arranges his

poj 3617 Best Cow Line(贪心)

 Best Cow Line Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8579   Accepted: 2629 Description FJ is about to take his N (1 ≤ N ≤ 2,000) cows to the annual"Farmer of the Year" competition. In this contest every farmer arranges h

POJ 3617 Best Cow Line (贪心)

题意: 给定长度为N的字符串S,要构造一个长度为N的字符串T.起初T是一个空串,随后反复进行下列任意操作 1.从字符串S头部删除一个字符,加到T的尾部 2.从字符串S尾部删除一个字符,加到T的尾部 目的是,构造字典序尽可能小的字符串T 思路:简单贪心,比较当前字符串S首尾字符的大小,选取小的加入T,若两者相同,则比较下一个字符. #include<stdio.h> #include<queue> #include<iostream> #include<algori

贪心/POJ 3617 Best Cow Line

1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 int main() 5 { 6 int n; 7 char s1[2020],s2[2020]; 8 scanf("%d",&n); 9 for (int i=0;i<n;i++) 10 { 11 char ch; 12 scanf(" %c",&ch); 13 s1[i]=ch; 14 }

POJ 3623 Best Cow Line, Gold(模拟)

题意  给你一个字符序列   你每次可以从它的头部或尾部拿出一个字符组成一个新的字符序列   输出这样做能达到的最小的字符序列   每行最多输出80个字符(开始被这个坑了好久) 直接模拟就行  哪边小就选哪边  相等就往内看 #include<cstdio> #include<iostream> #include<string> using namespace std; const int N = 30010; int main() { char s[N][2]; in

POJ 3623 Best Cow Line, Gold(字符串处理)

题意:给你一个字符串,让你重新排列,只能从头或者尾部取出一个放到新字符串队列的最后.按照字典序. 解决方法:比较前后两个的大小,谁小输出谁,相等,就往当中比来确定当前应该拿最前面的还是最后面的,如果再相等就继续.... 所以比较这个动作的单一功能,可以写成一个check函数,方便操作也方便递归. #include<iostream> #include<cstring> using namespace std; #define MAX 30005 char str[MAX]; int

[贪心+后缀数组] poj 3623 Best Cow Line, Gold

题意: 给N个字符,每次只能取第一个或者最后一个,问构成最小字典序的串是什么. 思路: 贪心,每次取字典序最小的串,的首字符. 其实就是l和r比较一下构成的串那个字典序小. 这里运用后缀数组要实现O(1)的查询. 将原串反拼进串内做da. 然后根据ra判断. 代码: #include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include&quo