#include <stdio.h> #include <string.h> //题目:电影院遇到卖票难题:有两类顾客,A类顾客只有100元钞票,B类顾客只有50元钞票。电影票价是50元,电影院售票处没有 //50元的零钱,所以卖票时就必须要考虑顺序问题。策略就是通过卖票给B类顾客,得到50元面值的钞票,然后才能顺利售票给A类 //顾客。 //程序要求输入A类和B类顾客的数量,然后输出所有可能的售票顺序。 //例如:A类顾客2位,B类顾客2位。则售票顺序可能是: //BABA BBAA //缺陷:由于字符序列只包含A、B两种字符,输出结果中有重复排列。如何去掉重复排列? //扫描字符串,如果字符串中任意长度的子串,其中含有字符B的数量大于字符A的数量,则返回1,否则返回0 //例如:字符串BABABA,则应该返回1;字符串BAABABABA,因为其中的字串BAA中A的数量大于B的数量,所以返回0 int scanStr(char *str) { int numA = 0, numB = 0, sign; char *p; char *q; for (p = str; *p != '/0'; p ++) { numB = 0; numA = 0; for (q = str; q <= p; q ++) { if (*q == 'A') numA ++; else if (*q == 'B') numB ++; if (numB >= numA) sign = 1; else { sign = 0; goto L; } } } L: return sign; } //值交换 void swap(char &a, char &b) { char temp; temp = a; a = b; b = temp; } //求出全排列,并输出符合条件的排列。这里参考全排列算法的一种递归实现方法。 void permutation(char *str, int left, int right) { int sign; if (left == right) { sign = scanStr(str); if (str[0] == 'B' && sign == 1) //满足限制条件 { printf("%s ", str); printf("/n"); } } else { for(int i = left; i < (right + 1); i++) { swap(str[left], str[i]); permutation(str, left + 1, right); swap(str[left], str[i]); } } } void main() { int m, n; char str[100] = ""; printf("请分别输入A类顾客和B类顾客的数量:"); scanf("%d %d", &m, &n); for(int i = 0; i < m; i++) str[i] = 'A'; for(int j = m; j < m + n; j++) str[j] = 'B'; printf("符合要求的卖票顺序有:/n"); permutation(str, 0, strlen(str) - 1); }