zoukankan      html  css  js  c++  java
  • 追溯法应用举例2-困难的串

    题目选自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("
    ");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("
    %d
    ",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 }
  • 相关阅读:
    航班预定统计(差分数组+前缀和)
    救生艇
    Xcode 的正确打开方式——Debugging
    多次页面跳转后pop回主界面的问题
    理解Bitcode:一种中间代码
    使用AFNetWorking读取JSON出现NSCocoaErrorDomain Code=3840的解决方法
    No identities are available for signing的解决方法
    Aufree/trip-to-iOS
    Alcatraz -- 一个神奇的管理插件的Xcode插件
    GenericKeychain
  • 原文地址:https://www.cnblogs.com/savennist/p/12205241.html
Copyright © 2011-2022 走看看