codeM美团编程大赛初赛B轮E题
题目描述
给出一个正整数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
这里我之前就写了一套可以将任意进制转换为2~62进制的代码,可以直接套用(注意仅针对非负数)。
要注意判断为yes时及时退出,避免无谓的后续计算,这里的思想总体来说属于暴力法,好像也只有这样了(摊手),不过还是要夸夸C++的stl库,效率不错。
有其他好方法记得留言交流哦!感谢!
该题还可以进一步优化,先找出t中的最大值,然后从该进制往上数,数到16时结束。
代码如下:
1 #include <iostream> 2 #include <string> 3 #include <cmath> 4 #include <algorithm> 5 6 using namespace std; 7 8 //将任意字符转换为十进制 9 long long convertToDec(char c) 10 { 11 long long decNum; 12 if(c>='a' && c<='z') 13 decNum=c-87; 14 else if(c>='A' && c<='Z') 15 decNum=c-29; 16 else if(c>='0' && c<='9') 17 decNum=c-48; 18 19 return decNum; 20 } 21 22 //将十进制转换为这些字符[0-9a-zA-Z],61个字符,最大表示62进制 23 char convertFromDec(long long c) 24 { 25 long long objchar; 26 if(c>=10 && c<=35) 27 objchar=c+87; 28 else if(c>=36 && c<=61) 29 objchar=c+29; 30 else if(c>=0 && c<=9) 31 objchar=c+48; 32 33 return objchar; 34 } 35 36 //从原进制转换为2~62的任意进制(src:源进制,obj:目标进制,num:源进制下的数) 37 string convert(int src,int obj,int num) 38 { 39 40 string num_str=to_string(num); 41 42 long long decNum=0;//十进制数(中间数) 43 for(long long i=0;i<num_str.size();++i) 44 decNum+=convertToDec(num_str[i])*pow(src,num_str.size()-1-i); 45 46 string strTmp; 47 long long tmp; 48 while(decNum>0) 49 { 50 tmp=decNum % obj; 51 strTmp=convertFromDec(tmp)+strTmp; 52 decNum/=obj; 53 } 54 return strTmp; 55 } 56 57 58 int main() 59 { 60 int n; 61 string t; 62 while(cin>>n>>t) 63 { 64 transform(t.begin(),t.end(),t.begin(),::tolower);//将t转换为小写了(因为本次题目用大写表示16进制的数,而我们的程序中是用小写表示16进制的) 65 bool Isyes=false; 66 //保存转换后的字符串,2~16进制共15种 67 vector<string> str_converted2To16(15); 68 //该题还可以进一步优化,先找出t中的最大值,然后从该进制往上数,数到16时结束(而不是从2往上数)。 69 for(int k=2;k<=16;++k) 70 { 71 //对1~n的每个数字进行转换 72 for(int i=1;i<=n;++i) 73 { 74 str_converted2To16[k-2]+=convert(10,k,i); 75 } 76 if(str_converted2To16[k-2].find(t)!=string::npos) 77 { 78 Isyes=true; 79 cout<<"yes"<<endl; 80 break; 81 } 82 } 83 if(!Isyes) 84 cout<<"no"<<endl; 85 } 86 return 0; 87 }
补充:
大小写转换函数请用全局命名空间中的函数,这也是lower前面要加::全局作用符的原因。因为有多个不同的版本。
『注:本文来自博客园“小溪的博客”,若非声明均为原创内容,请勿用于商业用途,转载请注明出处http://www.cnblogs.com/xiaoxi666/』
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性