poj_1256_回溯

题目描述:

   例举字母全排列并打印的问题。

 

解题思路:

   几个注意点:(1)字符串排序问题,符合A<a<B<b^^^。注意cmp的返回值是int,因此需要*10后返回;

(2)删除出现过的字母的问题。回溯做全排列,由于字符串长度最大为13,所以全部存结果排序后删除重复是不可行的,因为13!过大,同时对每个可能的结果串打标记也过大,不可行。考虑在回溯过程中做改动,删除回溯的每一层中重复穷举的情况,因此在回溯函数中设计局部标记数组,标记改字母位于该位置(每一层回溯对应一个字符所处的位置)是否已经穷举过了。

 

代码:

#include <stdio.h>
#include <stdlib.h>
#define LEN 14

char str[LEN], len, letter[LEN], tmp[LEN];
int f[LEN];

int cmp(const void *a, const void *b)
{
   double a1 = (double)(*(char*)a);
   double b1 = (double)(*(char*)b);
  
   if( a1 <= 90.0)
      a1 += 31.5;
   if( b1 <= 90.0)
      b1 += 31.5;
   //printf("%c %c %lf %lf\n",*((char*)a),*((char*)b),a1,b1);
   return (int)((a1- b1) * 10);
}

void permution(int num) 
{
   int i;
   int flag[130] = {0};//标记递归这一层里,这个字母是否已经穷举过。
   if(num == len)
   {
      if(strcmp(tmp,letter) != 0)
      {
          printf("%s\n",letter); //加下查重判断
          strcpy(tmp,letter);
      }
   }
   else
   {
      for(i=0;i<len;i++)
          if(f[i]==0 && flag[str[i]] == 0)
          {
             letter[num] = str[i];
             f[i] = 1;
             flag[str[i]] = 1;
             permution(num+1);
             f[i] = 0;
          }
   }
}

main()
{
   int n;
   scanf("%d",&n);
   while(n>0)
   {
      n--;
      scanf("%s",str);
      len = strlen(str);
      //对str排序
      qsort(str,len,sizeof(char),cmp);
      //printf("str:%s\n",str);
      memset(letter,0,LEN);
      memset(f,0,LEN);
      permution(0);
   }
   system("pause");
   return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值