码迷,mamicode.com
首页 > 其他好文 > 详细

追溯法应用举例2-困难的串

时间:2020-01-17 13:45:07      阅读:86      评论:0      收藏:0      [点我收藏+]

标签:eof   验证   下标   ems   用处   pac   div   ==   数组   

题目选自UVA-129:https://vjudge.net/problem/UVA-129

在刘汝佳的紫书中,曾经强调利用八皇后中的思想,借助字符串的后缀来生成数据。不需要刻意验证当下递归中所添加的字母是否同以后添加的字母满足题目关系。这一点与八皇后代码中按照每行或每列逐一递归的思想是相吻合的。在我的代码中,对于每一次添加的字符,都需要与前方已经添加好的相邻的字符组合并对比,以此来检查它是否满足了简单的串的定义。借助一维数组,如果此时需要填充的位置下标是cur,而填充的字母与前面相邻的字母组成了长度为k的子串,那么对比与该子串相邻的前方的长度同样为k的子串即可。(很明显,k==1表示对比cur处讨论的字符与cur-1处的字符的关系)。

代码如下:

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 int n,L;
 5 int aim[100];//使用数字代表字母,借鉴了紫书里的想法
 6 int allok=0;
 7 int cnt;
 8 int strpre(int* s,int* c,int lenth)
 9 {
10     for(int i=0;i<lenth;i++)
11         if(s[i]!=c[i])return 0;
12     return 1;
13 }
14 
15 int outer(int cur)//按照题目格式输出
16 {
17     int lenth=cur;
18     int gnum=0;
19     int per=0;
20     int start=0;
21     for(int i=0;i<cur;i++)
22     {
23         if(start&&per==0)
24         {
25             if(gnum==15){printf("\n");gnum=0;}//经过实验,发现是15而非16
26             else {gnum++;printf(" ");}
27         }
28         start=1;
29         printf("%c",aim[i]+A);
30         per++;
31         per=per%4;
32     }
33     printf("\n%d\n",lenth);
34     return 0;
35 }
36 
37 int solve(int cur)
38 {
39     if(allok)return 0;
40     if(cnt==n)
41     {
42         outer(cur);
43         allok=1;
44         return 0;
45     }
46     for(int i=0;i<L;i++)
47     {
48         if(cur==0)
49         {
50             aim[0]=i;
51             cnt++;
52             solve(1);
53             continue;
54         }
55         //if(aim[cur-1]==i)continue;//该句的作用已经被下面的for循环所取代
56         aim[cur]=i;
57         int ok=1;
58         for(int k=1;2*k<=cur+1;k++)//后缀字符的组合对比
59         {
60             int* temp1=&aim[cur]-(k-1);
61             int* temp2=temp1-k;
62             if(strpre(temp1,temp2,k))
63             {
64                 ok=0;
65                 break;
66             }
67         }
68         if(ok){cnt++;solve(cur+1);}
69     }
70     return 0;
71 }
72 
73 int main()
74 {
75     while(scanf("%d%d",&n,&L)&&n&&L)
76     {
77         allok=0;//注意初始化
78         cnt=0;
79         memset(aim,0,sizeof(aim));//这句并没有什么用处
80         solve(0);
81     }
82     return 0;
83 }

追溯法应用举例2-困难的串

标签:eof   验证   下标   ems   用处   pac   div   ==   数组   

原文地址:https://www.cnblogs.com/savennist/p/12205241.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!