首页 > 代码库 > CF 379D NewYearLetter [dp+暴力]
CF 379D NewYearLetter [dp+暴力]
题意:
给出k,x,n,m
找出这样的字符串s1,s2,s1长为n,s2长为m
给出规则,sn=sn-1+sn-2
使得第Sk项出现x个"AC"子串
我们很容易知道k次运算后有几个12,几个21,几个22子串,有几个串1,有几个串2
如果我们知道s1中出现了几个AC,s2中出现了几个AC
s1头和尾,s2头和尾巴
我们就能算出k次后能出现几个AC
现在正好反过来,我们都不知道s1,s2,我们要找出这样的s1,s2
那么我们枚举
s1头和尾,s2头和尾巴
s1中出现了几个AC,s2中出现了几个AC
算出来的Sk里面出现的AC数和x是否相等
直到枚举出来这样的
没有的话就输出happy new year
#include <cstdio> #include <cstring> #include <cmath> #include <iostream> #include <algorithm> using namespace std; long long k,x,n,m; long long lastnum[4][4]; long long num[4][4]; long long x1=1,x2=0; long long xx1=0,xx2=1; long long tmp[4][4]; void copy(long long to[][4],long long from[][4]){ for(long long i=1;i<=2;i++) for(long long j=1;j<=2;j++) to[i][j]=from[i][j]; } void add(long long to[][4],long long from[][4]){ for(long long i=1;i<=2;i++) for(long long j=1;j<=2;j++) to[i][j]+=from[i][j]; } long long ac_num(char* s){ long long cnt=0; long long len=strlen(s); for(long long i=0;i<len;i++) if(s[i]=='A' && s[i]=='C') cnt++; return cnt; } bool can(long long num1,long long num2,long long suf1,long long suf2,long long pre1,long long pre2){ if(xx1*num1+xx2*num2+ num[1][2]*(suf1=='A' && pre2=='C')+ num[2][2]*(suf2=='A' && pre2=='C')+ num[2][1]*(suf2=='A' && pre1=='C') ==x){ ///cout<<"n::"<<num[1][2]<<' '<<num[2][2]<<' '<<num[2][1]<<endl; return true; }else return false; } bool print(long long num1,long long num2, char suf1,char suf2,char pre1,char pre2){ if(n==1 && pre1 != suf1) return false; if(m==1 && pre2 != suf2) return false; if(n%2==0){ if(num1==n/2) if(!(suf1=='C' && pre1=='A')) return false; }else if(num1==n/2)if ((!(pre1=='A'||suf1=='C'))&&(n!=1))return false; if(m%2==0){ if(num2==m/2) if(!(suf2=='C' && pre2=='A')) return false; }else if(num2==m/2) if ((!(pre2=='A'||suf2=='C'))&&(m!=1)) return false; if(n%2==0){ if(num1==n/2){ for(long long i=1;i<=num1;i++) cout<<"AC"; }else{ cout<<pre1; for(long long i=1;i<=num1;i++) cout<<"AC"; for(long long i=1;i<=n-num1*2-2;i++) cout<<"B"; cout<<suf1; } }else{ if(num1==n/2){ if(n==1) cout<<pre1; else if(pre1=='A'){ for(long long i=1;i<=num1;i++) cout<<"AC"; cout<<suf1; }else if(suf1=='C'){ cout<<pre1; for(long long i=1;i<=num1;i++) cout<<"AC"; } }else{ cout<<pre1; for(long long i=1;i<=num1;i++) cout<<"AC"; for(long long i=1;i<=n-num1*2-2;i++) cout<<"B"; cout<<suf1; } } cout<<endl; if(m%2==0){ if(num2==m/2){ for(long long i=1;i<=num2;i++) cout<<"AC"; }else{ cout<<pre2; for(long long i=1;i<=num2;i++) cout<<"AC"; for(long long i=1;i<=m-num2*2-2;i++) cout<<"B"; cout<<suf2; } }else{ if(num2==m/2){ if(m==1) cout<<pre2; else if(pre2=='A'){ for(long long i=1;i<=num2;i++) cout<<"AC"; cout<<suf2; }else if(suf2=='C'){ cout<<pre2; for(long long i=1;i<=num2;i++) cout<<"AC"; } }else{ cout<<pre2; for(long long i=1;i<=num2-1;i++) cout<<"AC"; for(long long i=1;i<=m-num2*2-2;i++) cout<<"B"; cout<<suf2; } } cout<<endl; return true; } int main(){ #ifndef ONLINE_JUDGE freopen("G:/in.txt","r",stdin); #endif cin>>k>>x>>n>>m; for(long long i=3;i<=k;i++){ long long xx1tmp=xx1,xx2tmp=xx2; xx1+=x1;xx2+=x2; x1=xx1tmp,x2=xx2tmp; copy(tmp,num); add(num,lastnum); copy(lastnum,tmp); if(i==3) num[1][2]=1; if(i>=4 && i%2==0) num[2][1]++; else if(i>=4) num[2][2]++; } for(long long num1=0;num1<=(n/2);num1++) for(long long num2=0;num2<=(m/2);num2++) for(long long suf1='A';suf1<='C';suf1++) for(long long suf2='A';suf2<='C';suf2++) for(long long pre1='A';pre1<='C';pre1++) for(long long pre2='A';pre2<='C';pre2++) if(can(num1,num2,suf1,suf2,pre1,pre2)){ ///cout<<xx1<<' '<<xx2<<endl; // cout<<num1<<' ' // <<num2<<' ' // <<(char)pre1<<' ' // <<(char)pre2<<' ' // <<(char)suf1<<' ' // <<(char)suf2<<' '<<endl; if(print(num1,num2,suf1,suf2,pre1,pre2)){ return 0; } } cout<<"Happy new year!"<<endl; }
CF 379D NewYearLetter [dp+暴力]
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。