NOIP 2000 提高组 复赛 单词接龙

NOIP 2000 提高组 复赛 单词接龙

1.程序编写过程中,发现接龙处的判断编写有误,马上着手修改。

2.样例通过,提交40分,错了测试点1-4.

3.下载测试点1一看,傻眼了,原来有这样的测试数据:

输入:

1
envelope
e

输出:

15
4.上述测试点是挺经典的,不容易考虑到。envelope envelope 拼接成envelopenvelope

5.归根结底,还是接龙处的编写出现严重失误。

6.修改,提交,还错测试点2-4.

7.下载测试点2数据一看,更是奇葩:

输入:

2
abababab
abababc
a

输出:

19

经理解后,输出结果应如下解释:

abababab

           abababab

                      abababc

8.应采用最小交叠,这样输出长度才最大,还是修改判断接龙处函数。

9.修改提交,错了测试点4,真是感慨,该题要考虑的情况真多啊,难不在深度优先遍历,难在接龙处判定。

10.测试点4数据也挺奇葩,接了半天龙,单词长度还不如单个的单词长。

输入:

8
no
new
name
never
national
necessary
ever
me
n

输出:

9

10.修改,提交AC。

11.该题奇难无比,不是难在深度优先遍历,而是难在接龙处的判断函数编写,真是服了,原来可以这样难。

附上AC代码,编译环境Dev-C++4.9.9.2

#include <stdio.h>
#include <string.h>
int n;
char input[60][100];
char head[10];
int vis[60];
char dragon[3000];
char cur[100];
int max=0;
int cmp(char *first,char *second){
    int len1,len2,i,j,k,len;
    len1=strlen(first);
    len2=strlen(second);
    len=len1>len2?len2:len1;
    if(strcmp(first,second)==0){
        i=len1-1;
        j=0;
        while(i<len1&&j<len2&&first[i]==second[j]){
            i++;//此处写成i--查了会
            j++;
        }
        if(j==len-1)
            return 0;
    }
    for(k=1;k<len;k++){//k=len-1的目的是避免 邻的两部分存在包含关系;仔细一想,这个思路不行,还是要从k=len判断,因其可能完全重合,无论怎么移,都重合。
        i=len1-k;
        j=0;
        while(i<len1&&j<len2&&first[i]==second[j]){
            i++;//此处写成i--查了会
            j++;
        }
        if(j==k)
            break;
    }
    if(k==len)
        return 0;
    if(j==k)
        return j;
}
void dfs(int step){
    int len,i,k,j,len2;
    char t[100];
    for(i=1;i<=2*n;i++)
        if(vis[i]==0){
            k=cmp(cur,input[i]);
            if(k>0){
                vis[i]=1;
                len=strlen(dragon);
                len2=strlen(input[i]);
                for(j=k;j<len2;j++)//字符串拼接
                    dragon[len+j-k]=input[i][j];
                dragon[len+len2-k]='\0';
                len2=strlen(dragon);
                if(max<len2)
                    max=len2;
                strcpy(t,cur);
                strcpy(cur,input[i]);
                dfs(step+1);
                strcpy(cur,t);
                dragon[len]='\0';
                vis[i]=0;
            }
        }
}
int main(){
    int i,j,len;
    memset(vis,0,sizeof(vis));
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        scanf("%s",input[i]);
        strcpy(input[n+i],input[i]);
    }
    scanf("%s",head);
    for(i=1;i<=2*n;i++){
        if(input[i][0]==head[0]){
            strcpy(dragon,input[i]);
            vis[i]=1;
            len=strlen(dragon);
            if(max<len)
                max=strlen(dragon);//要过测试点4,此处必须对max赋值
            strcpy(cur,input[i]);
            dfs(1);
            vis[i]=0;
        }
    }
    printf("%d\n",max);
    return 0;
}

2017-3-31 22:05


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值