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;  
}  
   
  

  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值