[编程题|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();
}
}