[编程题|1500分] 子串
给出一个正整数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
思想:
按照题目意思的逻辑来就行了,这里还要注意的是 用java A题的时候 累加字符串不要用String 要用StringBuilder 不然很容易会超时!!!
写了一个S(n,k)的二进制转换函数 其它的都是调用API 如整数i转化k进制(Integer.toString(i, k).toUpperCase())
做了一点小小的优化,求出t串中字符的最大值max,这样就可以使k(进制)从max+1到16遍历(不必从2到16遍历)
JAVA AC代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Main m = new Main();
Scanner in = new Scanner(System.in);
while (in.hasNext()) {//注意while处理多个case
boolean flag = false;
int n = in.nextInt();
String t = in.next();
///max指的是t串里的字符的最大值
int max = 0;
for(int i=0;i<t.length();i++){
int temp = t.charAt(i)-'0';
if(temp>max)
max = temp;
}
//这里是指的如果最大值是 A B C D E F 转成 max= 10 11 12 13 14
if(max>=10)
max = max-17+10;
//System.out.println("max="+max);
for(int i=max+1;i<=16;i++){
if(m.s(n,i).indexOf(t)!=-1){
flag = true;
break;
}
}
if(flag)
System.out.println("yes");
else
System.out.println("no");
// System.out.println(m.s(16,16));
//System.out.println(m.s(5,2));
}
}
///求字符串s(n,k) 如s(16,16)=123456789ABCDEF10
String s(int n,int k){
StringBuilder s1 = new StringBuilder("");
for(int i=1;i<=n;i++){
s1.append(Integer.toString(i, k).toUpperCase());
// System.out.println(s1);
}
return s1.toString();
}
}

探讨了如何判断一个字符串是否能作为特定范围内整数在某一进制下的连接子串出现,通过优化算法减少不必要的进制遍历。
753

被折叠的 条评论
为什么被折叠?



