1. 程式人生 > >CodeM初賽B輪

CodeM初賽B輪

-m 什麽 sta 暴力枚舉 getch int cde etc space

做什麽啊,我這麽菜,應該棄賽的

[編程|1500分] 子串

時間限制:3秒
空間限制:32768K

題目描述

給出一個正整數n,我們把1..n在k進制下的表示連起來記為s(n,k),例如s(16,16)=123456789ABCDEF10, s(5,2)=11011100101。現在對於給定的n和字符串t,我們想知道是否存在一個k(2 ≤ k ≤ 16),使得t是s(n,k)的子串。

輸入描述:

第一行一個整數n(1 ≤ n ≤ 50,000)。
第二行一個字符串t(長度 ≤ 1,000,000)


輸出描述:

"yes"表示存在滿足條件的k,否則輸出"no"

輸入例子:

8
01112

輸出例子:

yes

這個題很簡單啊,這一場的手速題

暴力枚舉KMP就好了,我想到了KMP但是沒有從網上找模板,找到模板發現自己還是想的不好,最後優化成了這個樣子,自我感覺還是很完美的

長度 ≤ 1,000,000,這個也是給我開數組的提示,竟然不坑,反正覺得2進制的1到50k還是不小的

#include <bits/stdc++.h>
using namespace std;
char s[1000005],t[1000005];
int nex[1000005];
int l;
char f[20];
void la(int n, int b) {
    static char c[16]= {0,1,2,3,4,5,6,7,8,9,
A,B,C,D,E,F}; l=0; while(n) { f[l++]=c[n%b]; n=n/b; } } void pre(char *p) { int i,n,k; n=strlen(p); nex[1]=nex[0]=0; k=0; for (i=2; i<=n; i++) { for(; k!=0&&p[k]!= p[i-1]; k=nex[k]); if(p[k]==p[i-1])k++; nex[i]=k; } }
int kmp(char *text, char *p) { int m,n,s,q; m=strlen(p); n=strlen(text); q=s=0; while (s<n) { for (q=nex[q]; q<m&&p[q]==text[s]; q++,s++); if (q== 0) s++; else if(q==m) { return 1; } } return 0; } int main() { int n; scanf("%d",&n); getchar(); for(int i=0; ; i++) { char c=getchar(); if(c==\n) { t[i]=0; break; } t[i]=c; } pre(t); for(int j=16; j>1; j--) { int b=0; for(int i=1; i<=n; i++) { la(i,j); for(int k=l-1; k>=0; k--) s[b++]=f[k]; } s[b]=0; if(kmp(s,t)) return 0*puts("yes"); } return 0*puts("no"); }

CodeM初賽B輪