USTCOJ 1324 Zipper 存储计算结果

来源:互联网 发布:s7-300编程手册 编辑:程序博客网 时间:2024/06/06 03:50

在USTCOJ的1324这道题中,当遇到tttttt tttttt tttttttttttt这样的输入实例时,如下伪代码片段效率非常低。因为有很多的重复计算在里面。可通过存储match函数调用结果减少重复计算。

int match(char *a, char *b, char *c){if *c = 0return 1if *a = *b = *c    return match(a+1, b, c+1) || match(a, b+1, c+1)if *a = *creturn match(a+1, b, c+1)if *b = *creturn match(a, b+1, c+1)return 0}

其中代码一是用数组来存储结果,代码二用stl里面的set存储参数对(pair)。代码中while循环的目的是为了减少递归层次,仅当不能判断应该从哪一个子串(a或/和b)中取字符到主串(c)时,才跳出循环开始递归操作。


代码一:

#include <cstdio>#include <cstring>#include <set>#include <utility>#define N 500using namespace std;char flag[N][N];char stra[N], strb[N], strc[2*N];int match(char *a, char *b, char *c){    while (*a || *b)    {        if(*c != *a && *c != *b)            return 0;                if(*a == *b)            break;        else        {                        if (*a == *c)                a++, c++;            else                b++, c++;        }    }    //此时*a == *c,所以两重递归    if (*a)    {        if (flag[a+1-stra][b-strb] == 0)        {            if (match(a+1, b, c+1))                return 1;            else                flag[a+1-stra][b-strb] = 1;        }        if (flag[a-stra][b+1-strb] == 0)        {            if (match(a, b+1, c+1))                return 1;            else                flag[a-stra][b+1-strb] = 1;        }        return 0;    }    //若*a == '\0',表示a、b字符串中的字符均已在c中匹配,故返回匹配成功    else        return 1;}int main(){    freopen("1324.in", "r", stdin);    freopen("1324.out", "w", stdout);    int n;    scanf("%d", &n);    for (int i = 1; i <= n; i++)    {        memset(&flag[0][0], 0, N*N*sizeof(flag[0][0]));        scanf("%s%s%s", stra, strb, strc);        if (match(stra, strb, strc))            printf("Data set %d: yes\n", i);        else            printf("Data set %d: no\n", i);    }    return 0;}

代码二:

#include <cstdio>#include <cstring>#include <set>#include <utility>using namespace std;typedef pair<char *, char *> MyType;set<MyType> dpresult;int match(char *a, char *b, char *c){    while (*a || *b)    {        if(*c != *a && *c != *b)            return 0;                if(*a == *b)            break;        else        {                        if (*a == *c)                a++, c++;            else                b++, c++;        }    }    //此时*a == *c,所以两重递归    if (*a)    {        MyType p(a+1, c+1);        if (dpresult.find(p) == dpresult.end())        {            if (match(a+1, b, c+1))                return 1;            else                dpresult.insert(p);        }        p.first = b+1;        if (dpresult.find(p) == dpresult.end())        {            if (match(a, b+1, c+1))                return 1;            else                dpresult.insert(p);        }        return 0;    }    //若*a == '\0',表示a、b字符串中的字符均已在c中匹配,故返回匹配成功    else        return 1;}int main(){    freopen("1324.in", "r", stdin);    freopen("1324.out", "w", stdout);    char a[500], b[500], c[1000];    int n;    scanf("%d", &n);    for (int i = 1; i <= n; i++)    {        dpresult.clear();        scanf("%s%s%s", a, b, c);        if (match(a, b, c))            printf("Data set %d: yes\n", i);        else            printf("Data set %d: no\n", i);    }    return 0;}



原创粉丝点击