Description
给你一个数字N(1<=N<10000),并且N的各个位上没有0
他想知道将N的每个位置上的数字全部拿出来,重新排列得到的所有数字的和是多少
比如122的所有排列为:122+212+221=555
Input
有多组输入数据,第一行为一个数字case,代表有多少组输入数据 (case<=20) 以下case行每行包含一个正整数N(1<=N<10000),N的意义如上所述
Output
一共case行,每行一个整数对应N的所有排列得到的数字的和
Sample Input
2 122 12
Sample Output
555 33
解题思路:求一个字符串的全排列问题,是看那本《C语言的科学与技术》,讲得非常好。递归方法来求。把前K个字符固定后,再递归的求剩下的字符的全排列即可,知道K等于字符的长度,就把字符串输出。同时还要考虑把字符串的第K个字符与后面的字符交换的情况。即:
ABCD-> 递归
BACD-> 递归
CBAD-> 递归
DBCA-> 递归
在本题中,还要考虑的一个问题是重复。如何避免重复的情况,在这我采取的是每次交换前,先判断被交换的i位置上的字符和K到i之间的字符是否有重复,有重复的话就不交换,这样这道题就可以做了。
//西电2012ACM校赛#include#include #include int nResult;void Add(char *str){ int nLen,tmp = 0,i; nLen = strlen(str); for (i = 0; i < nLen; i++) { tmp+=(str[i] - '0') * (int)pow(10,nLen-i-1); } nResult += tmp;}void SwapStr(char *str,int k,int i){ char tmp; tmp = str[k]; str[k] = str[i]; str[i] = tmp;}int IsSwap(char *str,int k,int i){ //return 0 表示不交换 //return 1 表示交换 int j; for (j = k; j < i; j++) { if (str[j] == str[i]) { return 0; } } return 1;}static void PermuteWithFixedPrefix(char *str,int k){ //前K个字符不变,求剩下的字符的全排列 int i; if (k == strlen(str)) { //printf("%s\n",str); Add(str); } else { for (i = k; i < strlen(str); i++) { if (IsSwap(str,k,i)) { SwapStr(str,k,i); PermuteWithFixedPrefix(str,k+1); SwapStr(str,k,i); //重新交换K和i位置的字符 } } }}static void ListPermutations(char *str){ PermuteWithFixedPrefix(str,0);}int main(){ char szNum[5]; int nCase; scanf("%d",&nCase); while (nCase) { nCase--; nResult = 0; scanf("%s",szNum); ListPermutations(szNum); printf("%d\n",nResult); } return 0;}