zoukankan      html  css  js  c++  java
  • Codeforces 176B Word Cut

    Description

    题面
    题目大意:给定两个串A,B,每一次可以翻转A串的两个部分,如A=XY->YX,问恰好经过K次操作变成B串的方案数

    Solution

    需要注意到一个问题:本质不同的串最多只有 (n-1)
    可以把A看成一个环,每一次翻转相当于改变一个起点
    于是我们可以归类为两种串:1.原串 2.非原串
    原串可以产生(n-1)个非原串,非原串可以产生 (n-2) 个非原串和 (1) 个原串
    注意到:变成所有的非原串的方案数都是一样的
    因为非原串中并不一定所有的都等于B,所以还需要枚举B等于哪几个非原串,判定加上几个非原串的贡献
    (f[i][0/1]) 表示产生原串的方案数和产生非原串的方案数
    (f[i][0]=f[i-1][1]*(n-1))
    (f[i][1]=f[i-1][0]+(n-2)*f[i-1][1])

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+10,mod=1e9+7;
    int ans=0,f[N][2],K,n;char a[N],b[N];
    inline bool check(int x){
    	for(int i=1;i<=n;i++){
    		if(a[x]!=b[i])return false;
    		x++;if(x==n+1)x=1;
    	}
    	return true;
    }
    int main(){
      scanf("%s%s%d",a+1,b+1,&K);
      n=strlen(a+1);
      f[0][0]=1;
      for(int i=1;i<=K;i++){
    	  f[i][0]=1ll*f[i-1][1]*(n-1)%mod;
    	  f[i][1]=(f[i-1][0]+1ll*f[i-1][1]*(n-2))%mod;
      }
      for(int i=1;i<=n;i++){
    	  if(check(i)){
    		  if(i==1)ans=(ans+f[K][0])%mod;
    		  else ans=(ans+f[K][1])%mod;
    	  }
      }
      cout<<ans<<endl;
      return 0;
    }
    
  • 相关阅读:
    flex布局以及相关属性
    css 选择器
    两侧定宽,中栏自适应布局
    两列定宽,一列自适应布局
    左列定宽,右列自适应布局
    Flex接收51单片机发送过来的16进制数据转换为String
    Flex与51单片机socket通信 策略问题
    sql For XML Path
    sql多对多探讨
    JavaScript
  • 原文地址:https://www.cnblogs.com/Yuzao/p/8458907.html
Copyright © 2011-2022 走看看