CodeForces Round #117 (182D) - Common Divisors

       昨晚的比赛以为是23:00开始的..能水半个多小时..结果是0:00..就没参加了..今天看第一名是Watashi..去年WordFinal冠军巫泽俊..Orz...刚才刷了两道水题..B题那也太水了..本题也就是利用了KMP中Fail数组的性质...

       见代码就好...


Program 代码1:

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#define oo 2000000000
#define ll long long
using namespace std; 
int fail[2][100005],len[2];
char s[2][100005];
int main()
{      
       int i,t,k,ans,l;
       scanf("%s%s",s[0]+1,s[1]+1);
       len[0]=strlen(s[0]+1); 
       len[1]=strlen(s[1]+1);
       l=min(len[0],len[1]);
       ans=0;
       for (i=1;i<=l;i++)
           if (s[0][i]!=s[1][i]) goto A;
       memset(fail,0,sizeof(fail));
       for (t=0;t<2;t++)
           for (i=2;i<=len[t];i++)
           {
                 k=fail[t][i-1];
                 while (k && s[t][k+1]!=s[t][i]) k=fail[t][k];
                 if (s[t][k+1]==s[t][i]) fail[t][i]=k+1;
           }  
       for (t=len[0]-fail[0][len[0]];t<=l;t++) 
       if (len[0]%t==0 && len[1]%t==0)
       {
              k=len[0];
              while (k>t) k=fail[0][k];
              if (k!=t) continue;
              k=len[1];
              while (k>t) k=fail[1][k];
              if (k!=t) continue;  
              ans++;
       }
       A: printf("%d\n",ans);
       return 0;
}

Program 代码2:

#include<iostream>
#include<stack>
#include<queue>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<cmath>
#define ll long long
#define oo 1000000007
#define MAXN 100010
using namespace std;   
char s[2][MAXN];
int fail[2][MAXN],len[2];
void kmp(int tp)
{
      int i,k;
      len[tp]=strlen(s[tp]+1);
      memset(fail[tp],0,sizeof(fail[tp])); 
      for (i=2;i<=len[tp];i++)
      {
              k=fail[tp][i-1];
              while (k && s[tp][k+1]!=s[tp][i]) k=fail[tp][k];
              if (s[tp][k+1]==s[tp][i]) fail[tp][i]=k+1;
      }
      return;
}
int gcd(int a,int b)
{
      if (!b) return a;
      return gcd(b,a%b); 
}
int judge(int tp)
{
      int i,t,x,ans=len[tp]; 
      for (i=len[tp];i;i=fail[tp][i])
      if (len[tp]%i==0)
      {  
            t=len[tp],x=len[tp]-i;
            while (x) 
            {
                 if (fail[tp][t]>x) t=fail[tp][t];
                 if (fail[tp][t]!=x) goto A;
                 t-=i;
                 x-=i;
            }
            ans=min(ans,i);
            A: ;
      }
      return ans;
}
int getans()
{
      int i,p,t;
      kmp(0),kmp(1);
      p=min(len[0],len[1]);   
      for (i=1;i<=p;i++)
         if (s[0][i]!=s[1][i]) return 0; 
      i=judge(0),p=judge(1);
      if (i!=p) return 0;
      int h=gcd(len[0],len[1]);
      p=0; 
      for (t=i;t<=h;t+=i) 
        if (h%t==0) p++;
      return p;
}
int main()
{  
      while (~scanf("%s%s",s[0]+1,s[1]+1)) printf("%d\n",getans());  
      return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值