题目
给出一个正整数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和字符串t,要我们判断t是否为s(n,k)的子串。
最直接的思路便是依次枚举出s(n,k)的所有可能的情况,并逐个进行判断。
程序整体思路清晰,但考虑到实现操作比较繁琐,宜分多个函数实现各个细节。
代码
#include<cstdio> #include<string> #include<algorithm> using namespace std; char a[1000001] = {0};//a字符数组用于临时接收字符串输入 char const *dir = "0123456789ABCDEF"; string t,s; void calc(int n,int k);//生成s(n,k) string oneChar(int i,int k);//返回k进制下数字i对应的字符串 bool check(int n);//判断是否能够找到符合条件的s(n,k) int main() { int n; scanf("%d\n%s",&n,a); t = a; printf("%s\n",check(n) ? "yes" : "no"); return 0; } void calc(int n,int k) { s.clear(); string temp; for(int i = 1;i <= n;i++) { temp = oneChar(i,k); s.append(temp); } } bool check(int n) { for(int k = 2;k <= 16;k++) { calc(n,k);//check函数内部,对s(n,k)做枚举 if(s.find(t) != -1) return true; } return false; } string oneChar(int i,int k) { string temp; do { temp.append(1, dir[i % k]);//考虑到10进制以上会以字母代表数字的情况,借助一个dir字符串实现 i /= k; }while(i != 0); reverse(temp.begin(),temp.end()); return temp; }