UVA - 11027 Palindromic Permutation

来源:互联网 发布:迅雷看看mac版 编辑:程序博客网 时间:2024/05/28 20:19

题意:觉得这里讲的不错 点击打开链接  ,详细看代码

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;const int MAXN = 35;char str[MAXN],result[MAXN],cword;int vis[130],word[MAXN],cnt;long long n,F[MAXN],len;long long count(){    long long sum = 0,ans;    for (int i = 0; i < cnt; i++)        sum += vis[word[i]];    ans = F[sum];    for (int i = 0; i < cnt; i++)        if (vis[word[i]] > 1)            ans /= F[vis[word[i]]];    return ans;}int dfs(int cur,long long num){    if (cur == len)        return num;    long long sum = 0;    for (int i = 0; i < cnt; i++){        if (vis[word[i]]){   //尝试将最小的排在最外面            vis[word[i]]--;               long long s = count();  //剩下的会产生多少可能            if (sum <= num && sum+s >= num){   //结果一定要在这两个数之间                result[cur] = word[i];                return dfs(cur+1,num-sum);             }            else sum += s;  //跳过当前的字典序,在加一个大的            vis[word[i]]++;        }    }    return -1;}int main(){    F[0] = F[1] = 1;    for (int i = 2; i < 16; i++)        F[i] = i * F[i-1];    int t,cas=1;    scanf("%d",&t);    while (t--){        scanf("%s%lld",str,&n);        int ok = 2;        len = strlen(str);        cnt = 0;        memset(vis,0,sizeof(vis));        for (int i = 0; i < len; i++){            if (!vis[str[i]])                word[cnt++] = str[i];            vis[str[i]]++;   //记录单词出现的次数        }        cword = 0;        sort(word,word+cnt);        for (int i = 0; i < cnt; i++){            if (vis[word[i]] % 2){  //奇数次的只能有一个                ok--;                vis[word[i]]--;                cword = word[i];            }        }        if (cnt == 1 && n > 1)            ok = 0;        if (ok > 0){            len /= 2;            for (int i = 0; i < cnt; i++)                vis[word[i]] /= 2;            ok = dfs(0,n);            if (ok > 0){                int t = len;                if (cword)                    result[t++] = cword;                for (int i = 0; i < len; i++)                    result[t++] = result[len-i-1];                result[t] = '\0';            }        }        printf("Case %d: %s\n",cas++,ok>0?result:"XXX");    }    return 0;}


原创粉丝点击