标签:
http://poj.org/problem?id=3617
题目大意:
1.给一串有顺序的大写字母,作为输入
2.每次把输入的第一个或是最后一个位置的字母拿出来,放到一个队列中
3.要求新队列的字典序最小
思路:
贪心算法
1.首尾字母不等的,取较小的
2.首位字母相等,比较下一轮的两个字母来决定取哪个(还是相等的话继续递归)
比如:ACDBCB
轮次 | 前状态 | 操作 | 后状态 |
1 |
old:ACDBCB new: |
A比B小,取A |
old:CDBCB new:A |
2 |
old:CDBCB new:A |
C比B大,取B |
old:CDBC new:AB |
3 |
old:CDBC new:AB |
首位C与C相等,比较下一轮的两个字母,D比B大,所以取后面的C |
old:CDB new:ABC |
4 |
old:CDB new:ABC |
C比B大,取B |
old:CD new:ABCB |
5 |
old:CD new:ABCB |
C比D大,取C |
old:D new:ABCBC |
6 |
old:D new:ABCBC |
只剩最后一个D,取D |
old: new:ABCBCD |
1 #include <stdio.h> 2 3 int n; //输入数量 4 char input[2001]; //原始序列 5 char output[2001]; //输出 6 7 char tmp[2000]; //逻辑无关,用来吃输入的回车 8 9 int main() 10 { 11 while (scanf("%d", &n) != EOF) 12 { 13 gets(tmp); //吃回车 14 15 //输入 16 for (int i = 0; i < n; i++) 17 { 18 input[i] = getchar(); 19 20 gets(tmp); //吃回车 21 } 22 23 //处理,贪心算法 24 int idx = 0; //输出的索引 25 26 int s = 0; //输入左侧索引 27 int e = n - 1; //输入右侧索引 28 while (s <= e) //没有遍历完 29 { 30 bool left = true; //true:取左侧 false:取右侧 31 32 for (int i = 0; s + i <= e; i++) //左侧s位置和右侧e位置比较。如果相等,则递归到下一层(左右两侧都缩进一位继续比较)。 33 { 34 if (input[s + i] < input[e - i]) //左侧较小的话取左侧 35 { 36 left = true; 37 break; 38 } 39 else if (input[s + i]>input[e - i]) //右侧较小的取右侧 40 { 41 left = false; 42 break; 43 } 44 //相等的话比较下一层 45 } 46 47 //装入输出数组中 48 if (left) 49 output[idx++] = input[s++]; 50 else 51 output[idx++] = input[e--]; 52 } 53 54 //输出 55 for (int i = 0; i < idx; i++) 56 { 57 putchar(output[i]); 58 if ((i + 1) % 80 == 0) //每80个换一行输出 59 { 60 printf("\n"); 61 } 62 } 63 printf("\n"); 64 65 } 66 67 return 0; 68 }
标签:
原文地址:http://www.cnblogs.com/iswoit/p/4450526.html