sdut 1465 公共因子

http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=1465

题意:中文.....

思路:

1:暴力枚举两个字符串长度的最大公倍数的因子,作为因子的长度,然后从s1中去出来,做比较,才开始手搓打错了一个地方导致一直tle.

2:同样是枚举两个字符串长度的最大公倍数的因子,作为因子的长度,然后从s1中去出来作比较,这里可以用kmp做,之际一路比较下去。

//#pragma comment(linker,"/STACK:327680000,327680000")  

#include <iostream>  

#include <cstdio>  

#include <cmath>  

#include <vector>  

#include <cstring>  

#include <algorithm>  

#include <string>  

#include <set>  

#include <functional>  

#include <numeric>  

#include <sstream>  

#include <stack>  

#include <map>  

#include <queue>  

  

#define CL(arr, val)    memset(arr, val, sizeof(arr))  

  

#define ll long long  

#define inf 0x7f7f7f7f  

#define lc l,m,rt<<1  

#define rc m + 1,r,rt<<1|1  

#define pi acos(-1.0)  

#define ll long long  

#define L(x)    (x) << 1  

#define R(x)    (x) << 1 | 1  

#define MID(l, r)   (l + r) >> 1  

#define Min(x, y)   (x) < (y) ? (x) : (y)  

#define Max(x, y)   (x) < (y) ? (y) : (x)  

#define E(x)        (1 << (x))  

#define iabs(x)     (x) < 0 ? -(x) : (x)  

#define OUT(x)  printf("%I64d\n", x)  

#define lowbit(x)   (x)&(-x)  

#define Read()  freopen("din.txt", "r", stdin)  

#define Write() freopen("dout.txt", "w", stdout);  

  

  

#define N 100007  

using namespace std;  

  

  

char s1[N],s2[N];  

char tmp[N],t[N];  

  

int n,m,nm;  

  

int gcd(int i,int j)  

{  

    if (j == 0) return i;  

    return gcd(j,i%j);  

}  

bool isNotOk(char *ts,char *tp,int len)  

{  

    int i;  

    for (i = 0; i < len; ++i)  

    {  

        if (ts[i] != tp[i]) return true;  

    }  

    return false;  

}  

int main()  

{  

  

     //Read();  

  

  int cnt,i,j,s;  

  while (~scanf("%s%s",s1,s2))  

  {  

      n = strlen(s1);  

      m = strlen(s2);  

      cnt = 0;  

      nm = gcd(n,m);  

  

      for (i = 1; i <= nm; ++i)  

      {  

         bool flag = false;  

         if (nm % i == 0)  

         {  

             for (j = 0; j < i; ++j)  

             tmp[j] = s1[j];  

             tmp[j] = '\0';  

  

             for (j = i; j <= n - i; j += i)  //这里是j+=i,手贱写成++了一直tle后来改过就A了

             {  

  

                int pos = 0;  

                for (s = j; s < j + i; ++s)  

                {  

                    t[pos++] = s1[s];  

                }  

                t[pos] = '\0';  

  

                if (isNotOk(tmp,t,i))  

                {  

                    flag = true;  

                    break;  

                }  

             }  

             if (flag) continue;  

  

            //printf("*************************************\n");  

  

             for (j = 0; j <= m - i; j += i)  

             {  

                int pos = 0;  

                for (s = j; s < j + i; ++s)  

                {  

                    t[pos++] = s2[s];  

                }  

                t[pos] = '\0';  

                if (isNotOk(tmp,t,i))  

                {  

                    flag = true;  

                    break;  

                }  

             }  

             if (flag) continue;  

             cnt++;  

         }  

      }  

      printf("%d\n",cnt);  

  }  

    return 0;  

}  

   

  

  

KMP版本:

//#pragma comment(linker,"/STACK:327680000,327680000")  

#include <iostream>  

#include <cstdio>  

#include <cmath>  

#include <vector>  

#include <cstring>  

#include <algorithm>  

#include <string>  

#include <set>  

#include <functional>  

#include <numeric>  

#include <sstream>  

#include <stack>  

#include <map>  

#include <queue>  

  

#define CL(arr, val)    memset(arr, val, sizeof(arr))  

  

#define ll long long  

#define inf 0x7f7f7f7f  

#define lc l,m,rt<<1  

#define rc m + 1,r,rt<<1|1  

#define pi acos(-1.0)  

#define ll long long  

#define L(x)    (x) << 1  

#define R(x)    (x) << 1 | 1  

#define MID(l, r)   (l + r) >> 1  

#define Min(x, y)   (x) < (y) ? (x) : (y)  

#define Max(x, y)   (x) < (y) ? (y) : (x)  

#define E(x)        (1 << (x))  

#define iabs(x)     (x) < 0 ? -(x) : (x)  

#define OUT(x)  printf("%I64d\n", x)  

#define lowbit(x)   (x)&(-x)  

#define Read()  freopen("din.txt", "r", stdin)  

#define Write() freopen("dout.txt", "w", stdout);  

  

  

#define N 100007  

using namespace std;  

  

  

char s1[N],s2[N];  

char tmp[N],t[N];  

int next1[N],next2[N];  

  

int n,m,nm,cnt;  

  

int gcd(int i,int j)  

{  

    if (j == 0) return i;  

    return gcd(j,i%j);  

}  

  

void getNext(char *s,int mk)  

{  

    int i,j;  

    j = -1;  

    int len = strlen(s);  

    if (mk == 1) next1[0] = -1;  

    else next2[0] = -1;  

    for (i = 1; i < len; ++i)  

    {  

        while (j > -1 && s[j + 1] != s[i])  

        {  

  

            if (mk == 1) j = next1[j];  

            else j = next2[j];  

        }  

  

        if (s[j + 1] == s[i]) ++j;  

  

        if (mk == 1) next1[i] = j;  

        else next2[i] = j;  

    }  

}  

int kmp(char *ts1,char *ts2,int mk)  

{  

    int len1 = strlen(ts1);  

    int len2 = strlen(ts2);  

  

    int i,j;  

    j = -1;  

    int ans = 0;  

    for (i = 0; i < len2; ++i)  

    {  

        while (j > -1 && ts1[j + 1] != ts2[i])  

        {  

            if (mk == 1) j = next1[j];  

            else j = next2[j];  

        }  

  

        if (ts1[j + 1] == ts2[i]) ++j;  

        if (j == len1 - 1)  

        {  

            ans++;  

            j = -1;  //这里继续往下比较

        }  

    }  

    return ans;  

}  

int main()  

{  

   // Read();  

    int i,j;  

    while (~scanf("%s%s",s1,s2))  

    {  

        n = strlen(s1);  

        m = strlen(s2);  

        nm = gcd(n,m);  

       // printf("%d\n",nm);  

  

        getNext(s1,1);  

        getNext(s2,2);  

        cnt = 0;  

        int ans;  

        for (i = 1; i <= nm; ++i)  

        {  

            if (nm % i == 0)  

            {  

                //printf(">>>%d\n",i);  

                for (j = 0; j < i; ++j)  

                tmp[j] = s1[j];  

                tmp[j] = '\0';  

//                if (n %i != 0 || m % i != 0)  

//                printf("CUOLE、\n");  

                ans = kmp(tmp,s1,1);  

                //printf("1>>%d %d\n",ans,n/i);  

                if (ans != n/i) continue;  

                ans = kmp(tmp,s2,2);  

               // printf("2>>%d %d\n\n",ans,m/i);  

                if (ans != m/i) continue;  

                cnt++;  

            }  

        }  

        printf("%d\n",cnt);  

    }  

    return 0;  

}  

   

  

  

 

你可能感兴趣的:(du)