题号 题目 知识点 难度 通过率
KS1 获得最多的奖金 数组贪心 中等 21.23%
KS2 将满二叉树转换为求和树 递归模拟 简单 25.24%
KS3 搭积木 排序动态规划 较难 16.35%
KS4 最少数量货物装箱问题 动态规划贪心 中等 31.94%
KS5 回文子串 字符串模拟动态规划 较难 36.79%
KS6 字符串长度最大乘积 字符串模拟 简单 29.19%
KS7 今年的第几天 模拟 简单 38.80%
KS8 数字序列第n位的值 简单 43.40%
KS9 字符串排序 排序字符串 入门 31.93%
KS10 回文字符串 字符串动态规划 中等 26.79%
KS11 latex爱好者 中等 16.81%
KS12 游戏海报 字符串模拟 入门 45.05%
KS13 合并数组 数组模拟 中等 18.09%
KS14 字符串包含 字符串模拟 中等 26.04%
KS15 魔法深渊 动态规划 中等 25.14%
KS16 善变的同伴 动态规划 中等 8.89%
KS17 字符串归一化 模拟字符串 入门 35.63%
KS18 a/b 模拟 中等 28.34%
KS19 最小代价爬楼梯 动态规划 中等 25.06%
KS20 字符串压缩 字符串模拟 简单 32.19%
KS21 解析加减法运算 字符串数组模拟 简单 32.59%
KS22 求连续子数组的最大和 动态规划数组贪心 中等 32.23%
KS23 非递减序列 排序数组穷举 中等 44.40%
KS24 求x到y的最少计算次数 队列 中等 27.13%
KS25 阶乘末尾非零数字 数学 中等 13.63%
KS26 字符串最小变换次数 动态规划字符串 中等 36.35%
KS27 二进制中有多少个1 位运算 简单 44.04%
KS28 计算斐波那契数最小差值 穷举 中等 36.68%
KS29 查找无重复最长子串 字符串哈希 中等 30.23%
KS30 情报 递归图动态规划 中等 25.95%
KS31 最大公共子串 字符串动态规划 较难 33.83%
KS32 找缺失数字 穷举字符串 中等 33.49%
KS33 寻找奇数 穷举 简单 22.80%
KS34 计算器 字符串模拟栈 中等 38.67%
KS35 机器人移动范围 图数组 中等 18.27%
KS36 判断一棵满二叉树是否为二叉搜索树 递归树 简单 13.65%
KS1 获得最多的奖金
题目描述
小明在越南旅游,参加了当地的娱乐活动。小明运气很好,拿到了大奖, 到了最后的拿奖金环节。小明发现桌子上放着一列红包,每个红包上写着奖金数额。
现在主持人给要求小明在这一列红包之间“切”2刀,将这一列红包“切”成3组,并且第一组的奖金之和等于最后一组奖金和(允许任意一组的红包集合是空)。最终第一组红包的奖金之和就是小明能拿到的总奖金。小明想知道最多能拿到的奖金是多少,你能帮他算算吗。
举例解释:桌子上放了红包 1, 2, 3, 4, 7, 10。小明在“4,7”之间、“7,10” 之间各切一刀,将红包分成3组 [1, 2, 3, 4] [7] [10],其中第一组奖金之和=第三组奖金之和=10,所以小明可以拿到10越南盾。
输入描述:
第一行包含一个正整数n,(1<=n<= 200 000),表示有多少个红包。
第二行包含n个正整数d[i],表示每个红包包含的奖金数额。其中1<= d[i] <= 1000 000 000
输出描述:
小明可以拿到的总奖金
示例1
输入
5
1 3 1 1 4
输出
5
说明
[1,3,1] [ ] [1,4] ,其中第一组奖金和是5,等于第三组奖金和。所以小明可以拿到5越南盾
示例2
输入
5
1 3 2 1 4
输出
4
说明
[1,3] [2,1] [4],小明可以拿到4越南盾
####示例3
输入
3
4 1 2
输出
0
说明
[ ] [4, 1, 2] [ ] ,小明没办法,为了保证第一组第三组相等,只能都分成空的。所以小明只能拿到0越南盾。
import java. io. BufferedReader;
import java. io. IOException;
import java. io. InputStreamReader;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader bf = new BufferedReader ( new InputStreamReader ( System. in) ) ;
int n = Integer. parseInt ( bf. readLine ( ) ) ;
String[ ] line2 = bf. readLine ( ) . split ( " " ) ;
int [ ] nums = new int [ n] ;
for ( int i = 0 ; i < n; i++ ) {
nums[ i] = Integer. parseInt ( line2[ i] ) ;
}
int left = 0 , right = n - 1 ;
long left_sum = nums[ left] , right_sum = nums[ right] , max_sum = 0 ;
while ( left < right) {
if ( left_sum == right_sum) {
max_sum = left_sum;
left_sum += nums[ ++ left] ;
right_sum += nums[ -- right] ;
} else if ( left_sum > right_sum) {
right_sum += nums[ -- right] ;
} else {
left_sum += nums[ ++ left] ;
}
}
System. out. println ( max_sum) ;
}
}
KS2 将满二叉树转换为求和树
题目描述
给出满二叉树,编写算法将其转化为求和树
什么是求和树:二叉树的求和树, 是一颗同样结构的二叉树,其树中的每个节点将包含原始树中的左子树和右子树的和。
二叉树:
10
/ \
-2 6
/ \ / \
8 -4 7 5
求和树:
20(4-2+12+6)
/ \
4(8-4) 12(7+5)
/ \ / \
0 0 0 0
二叉树给出前序和中序输入,求和树要求中序输出;
所有处理数据不会大于int;
输入描述:
2行整数,第1行表示二叉树的前序遍历,第2行表示二叉树的中序遍历,以空格分割
输出描述:
1行整数,表示求和树的中序遍历,以空格分割
示例1
输入
10 -2 8 -4 6 7 5
8 -2 -4 10 7 6 5
输出
0 4 0 20 0 12 0
import java. io. BufferedReader;
import java. io. IOException;
import java. io. InputStreamReader;
import java. util. Arrays;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String s1 = bufferedReader. readLine ( ) ;
String s2 = bufferedReader. readLine ( ) ;
String[ ] preOrder = s1. split ( " " ) ;
String[ ] inOrder = s2. split ( " " ) ;
int [ ] res = new int [ inOrder. length] ;
for ( int i = 0 ; i < inOrder. length; i++ ) {
res[ i] = Integer. parseInt ( inOrder[ i] ) ;
}
dfs ( res, 0 , inOrder. length - 1 ) ;
for ( int r : res) System. out. print ( r + " " ) ;
}
private static int dfs ( int [ ] res, int left, int right) {
if ( left == right) {
int temp = res[ left] ;
res[ left] = 0 ;
return temp;
}
int mid = ( right - left) / 2 + left;
int leftSum = dfs ( res, left, mid - 1 ) ;
int rightSum = dfs ( res, mid + 1 , right) ;
int temp = res[ mid] ;
res[ mid] = leftSum + rightSum;
return res[ mid] + temp;
}
}
KS3 搭积木
题目描述
小明有一袋子长方形的积木,如果一个积木A的长和宽都不大于另外一个积木B的长和宽,则积木A可以搭在积木B的上面。好奇的小明特别想知道这一袋子积木最多可以搭多少层,你能帮他想想办法吗?
定义每一个长方形的长L和宽W都为正整数,并且1 <= W <= L <= INT_MAX, 袋子里面长方形的个数为N, 并且 1 <= N <= 1000000.
假如袋子里共有5个积木分别为 (2, 2), (2, 4), (3, 3), (2, 5), (4, 5), 则不难判断这些积木最多可以搭成4层, 因为(2, 2) < (2, 4) < (2, 5) < (4, 5)。
输入描述:
第一行为积木的总个数 N
之后一共有N行,分别对应于每一个积木的宽W和长L
输出描述:
输出总共可以搭的层数
示例1
输入
5
2 2
2 4
3 3
2 5
4 5
输出
4
import java. io. BufferedReader;
import java. io. IOException;
import java. io. InputStreamReader;
import java. util. *;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader bf = new BufferedReader ( new InputStreamReader ( System. in) ) ;
int n = Integer. parseInt ( bf. readLine ( ) ) ;
int [ ] [ ] arr = new int [ n] [ 2 ] ;
for ( int i = 0 ; i < n; i++ ) {
String[ ] s = bf. readLine ( ) . split ( " " ) ;
arr[ i] [ 0 ] = Integer. parseInt ( s[ 0 ] ) ;
arr[ i] [ 1 ] = Integer. parseInt ( s[ 1 ] ) ;
}
bf. close ( ) ;
if ( n == 1 ) {
System. out. println ( 1 ) ;
return ;
}
Arrays. sort ( arr, Comparator. comparingInt ( o - > o[ 0 ] ) ) ;
int [ ] dp = new int [ n] ;
dp[ 0 ] = 1 ;
int count = 0 ;
for ( int i = 0 ; i < n; i++ ) {
int val = arr[ i] [ 1 ] ;
int l = 0 ;
int r = count;
while ( l < r) {
int mid = l + ( r - l) / 2 ;
if ( dp[ mid] > val)
r = mid;
else
l = mid + 1 ;
}
if ( l == count)
count++ ;
dp[ l] = val;
}
System. out. println ( count) ;
}
}
KS4 最少数量货物装箱问题
题目描述
有重量分别为3,5,7公斤的三种货物,和一个载重量为X公斤的箱子(不考虑体积等其它因素,只计算重量)
需要向箱子内装满X公斤的货物,要求使用的货物个数尽可能少(三种货物数量无限)
输入描述:
输入箱子载重量X(1 <= X <= 10000),一个整数。
输出描述:
如果无法装满,输出 -1。
如果可以装满,输出使用货物的总个数。
示例1
输入
4
输出
-1
说明
无法装满
示例2
输入
8
输出
2
说明
使用1个5公斤,1个3公斤货物
import java. io. *;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader bf = new BufferedReader ( new InputStreamReader ( System. in) ) ;
int X = Integer. parseInt ( bf. readLine ( ) ) ;
int [ ] w = new int [ ] { 3 , 5 , 7 } ;
int [ ] dp = new int [ X + 1 ] ;
for ( int k : w) {
for ( int j = k; j <= X; j++ ) {
if ( j % k == 0 ) {
dp[ j] = dp[ j - k] + 1 ;
} else if ( dp[ j - k] != 0 ) {
dp[ j] = dp[ j - k] + 1 ;
}
}
}
System. out. println ( dp[ X] == 0 ? - 1 : dp[ X] ) ;
}
}
KS5 回文子串
题目描述
给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。
("回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。)
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被计为是不同的子串。
可用C++,Java,C#实现相关代码逻辑
输入描述:
输入一个字符串S 例如“aabcb”(1 <= |S| <= 50), |S|表示字符串S的长度。
输出描述:
符合条件的字符串有"a","a","aa","b","c","b","bcb"
所以答案:7
示例1
输入
aabcb
输出
7
import java. io. *;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader bf = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String s = bf. readLine ( ) ;
int count = 0 , len = s. length ( ) ;
for ( int i = 0 ; i < len; i++ ) {
for ( int j = i + 1 ; j <= len; j++ ) {
if ( same ( s. substring ( i, j) ) ) {
count++ ;
}
}
}
System. out. print ( count) ;
}
private static boolean same ( String s) {
char [ ] chars = s. toCharArray ( ) ;
int left = 0 , right = chars. length - 1 ;
while ( left < right) {
if ( chars[ left++ ] != chars[ right-- ] ) {
return false ;
}
}
return true ;
}
}
KS6 字符串长度最大乘积
题目描述
已知一个字符串数组words,要求寻找其中两个没有重复字符的字符串,使得这两个字符串的长度乘积最大,输出这个最大的乘积。如:
words=["abcd","wxyh","defgh"], 其中不包含重复字符的两个字符串是"abcd"和"wxyh",则输出16
words=["a","aa","aaa","aaaa"], 找不到满足要求的两个字符串,则输出0
输入描述:
Input:
["a","ab","abc","cd","bcd","abcd"]
输出描述:
Output:
4
示例1
输入
["a","ab","abc","cd","bcd","abcd"]
输出
4
备注:
Input中,不包含相同字符的有三对:
"ab"和"cd"
"a"和"cd"
"a"和"bcd"
所以字符串长度乘积的最大值是4
import java. io. *;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader reder = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String inputStr = reder. readLine ( ) ;
String[ ] strs = inputStr. substring ( 1 , inputStr. length ( ) - 1 ) . split ( "," ) ;
int max = 0 ;
for ( int i = 0 ; i < strs. length; i++ ) {
for ( int j = i + 1 ; j < strs. length; j++ ) {
max = Math. max ( compute ( strs[ i] , strs[ j] ) , max) ;
}
}
System. out. println ( max) ;
}
public static int compute ( String strs1, String strs2) {
for ( int i = 1 ; i < strs1. length ( ) - 1 ; i++ ) {
for ( int j = 1 ; j < strs2. length ( ) - 1 ; j++ ) {
if ( strs1. charAt ( i) == strs2. charAt ( j) ) {
return 0 ;
}
}
}
return ( strs1. length ( ) - 2 ) * ( strs2. length ( ) - 2 ) ;
}
}
KS7 今年的第几天
题目描述
输入年、月、日,计算该天是本年的第几天。
输入:
包括三个整数年(1<=Y<=3000)、月(1<=M<=12)、日(1<=D<=31)。
输出:
输入可能有多组测试数据,对于每一组测试数据,
输出一个整数,代表Input中的年、月、日对应本年的第几天。
输入描述:
输入:1990 9 20
输出描述:
输入:263
示例1
输入
2000 5 1
输出
122
####备注:
注意闰年的判定方式
import java. io. BufferedReader;
import java. io. InputStreamReader;
import java. io. IOException;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String[ ] a = br. readLine ( ) . split ( " " ) ;
int year = Integer. parseInt ( a[ 0 ] ) ;
int month = Integer. parseInt ( a[ 1 ] ) ;
int day = Integer. parseInt ( a[ 2 ] ) ;
int [ ] md = { 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 } ;
if ( ( year % 4 == 0 && year % 100 != 0 ) || year % 400 == 0 ) {
md[ 1 ] ++ ;
}
for ( int i = 0 ; i < month - 1 ; i++ ) {
day += md[ i] ;
}
System. out. println ( day) ;
}
}
KS8 数字序列第n位的值
题目描述
有一个无限长的数字序列1,2,2,3,3,3,4,4,4,4,5,5,5,5,5。。。(数字序列从1开始递增,且数字k在该序列中正好出现k次),求第n项是多少
输入描述:
输入为一个整数n
输出描述:
输出一个整数,即第n项的值
示例1
输入
4
输出
3
备注:
如:输入为3,有序数列第3项的值为2,则输出为2
import java. io. *;
import java. util. *;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader reader = new BufferedReader ( new InputStreamReader ( System. in) ) ;
int num = Integer. parseInt ( reader. readLine ( ) ) ;
System. out. print ( getN ( num) ) ;
}
public static int getN ( int num) {
int sum = 0 ;
int i = 1 ;
while ( sum < num) {
sum += i;
i++ ;
}
return i - 1 ;
}
}
KS9 字符串排序
题目描述
月神拿到一个新的数据集,其中每个样本都是一个字符串(长度小于100),样本的的后六位是纯数字,月神需要将所有样本的后六位数字提出来,转换成数字,并排序输出。
月神要实现这样一个很简单的功能确没有时间,作为好朋友的你,一定能解决月神的烦恼,对吧。
输入描述:
每个测试用例的第一行是一个正整数M(1<=M<=100),表示数据集的样本数目
接下来输入M行,每行是数据集的一个样本,每个样本均是字符串,且后六位是数字字符。
输出描述:
对每个数据集,输出所有样本的后六位构成的数字排序后的结果(每行输出一个样本的结果)
示例1
输入
4
abc123455
boyxx213456
cba312456
cdwxa654321
输出
123455
213456
312456
654321
import java. io. BufferedReader;
import java. io. InputStreamReader;
import java. io. IOException;
import java. util. Arrays;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System. in) ) ;
int n = Integer. parseInt ( br. readLine ( ) ) ;
int [ ] arr = new int [ n] ;
for ( int i = 0 ; i < n; i++ ) {
String s = br. readLine ( ) ;
arr[ i] = Integer. parseInt ( s. substring ( s. length ( ) - 6 ) ) ;
}
Arrays. sort ( arr) ;
for ( int i = 0 ; i < n; i++ ) {
System. out. println ( arr[ i] ) ;
}
}
}
KS10 回文字符串
题目描述
最大回文子串是被研究得比较多的一个经典问题。最近月神想到了一个变种,对于一个字符串,如果不要求子串连续,那么一个字符串的最大回文子串的最大长度是多少呢。
输入描述:
每个测试用例输入一行字符串(由数字0-9,字母a-z、A-Z构成),字条串长度大于0且不大于1000.
输出描述:
输出该字符串的最长回文子串的长度。(不要求输出最长回文串,并且子串不要求连续)
示例1
输入
adbca
输出
3
说明
因为在本题中,不要求回文子串连续,故最长回文子串为aba(或ada、aca)
####备注:
因为不要求子串连续,所以字符串abc的子串有a、b、c、ab、ac、bc、abc7个
import java. io. *;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System. in) ) ;
char [ ] c = br. readLine ( ) . toCharArray ( ) ;
int len = c. length;
int [ ] [ ] dp = new int [ len] [ len] ;
for ( int i = 0 ; i < len; i++ ) {
dp[ i] [ i] = 1 ;
}
for ( int i = len - 2 ; i >= 0 ; i-- ) {
for ( int j = i + 1 ; j < len; j++ ) {
if ( c[ i] == c[ j] ) {
dp[ i] [ j] = dp[ i + 1 ] [ j - 1 ] + 2 ;
} else dp[ i] [ j] = Math. max ( dp[ i + 1 ] [ j] , dp[ i] [ j - 1 ] ) ;
}
}
System. out. println ( dp[ 0 ] [ len - 1 ] ) ;
}
}
KS11 latex爱好者
题目描述
latex自然是广大研究人员最喜欢使用的科研论文排版工具之一。
月神想在iPhone 上查阅写好的paper,但是无赖iPhone 上没有月神喜欢使用的阅读软件,于是月神也希望像tex老爷爷Donald Knuth那样自己动手do it yourself一个。
在DIY这个阅读软件的过程中,月神碰到一个问题,已知iPhone屏幕的高为H,宽为W,若字体大小为S(假设为方形),则一行可放W / S(取整数部分)个文字,一屏最多可放H / S (取整数部分)行文字。
已知一篇paper有N个段落,每个段落的文字数目由a1, a2, a3,...., an表示,月神希望排版的页数不多于P页(一屏显示一页),那么月神最多可使用多大的字体呢?
1 <= W, H, ai <= 1000
1 <= P <= 1000000
输入描述:
每个测试用例的输入包含两行。
第一行输入N,P,H,W
第二行输入N个数a1,a2,a3,...,an表示每个段落的文字个数。
输出描述:
对于每个测试用例,输出最大允许的字符大小S
示例1
输入
1 10 4 3 10 2 10 4 3 10 10
输出
3 2
import java. io. *;
public class Main {
public static void main ( String[ ] args) throws Exception {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String[ ] str1 = br. readLine ( ) . split ( " " ) ;
int P = Integer. parseInt ( str1[ 1 ] ) ;
int H = Integer. parseInt ( str1[ 2 ] ) ;
int W = Integer. parseInt ( str1[ 3 ] ) ;
String[ ] str2 = br. readLine ( ) . split ( " " ) ;
int totalNum = 0 ;
for ( String s : str2) {
totalNum += Integer. parseInt ( s) ;
}
System. out. println ( process ( P, H, W, totalNum) ) ;
}
public static int process ( int P, int H, int W, int totalNum) {
int perPaperNum = ( totalNum + P - 1 ) / P;
int left = 1 ;
int right = Math. min ( H, W) ;
while ( left <= right) {
int mid = left + ( right - left) / 2 ;
int num = ( H / mid) * ( W / mid) ;
if ( num >= perPaperNum) {
left = mid + 1 ;
} else {
right = mid - 1 ;
}
}
return right;
}
}
KS12 游戏海报
题目描述
小明有26种游戏海报,用小写字母"a"到"z"表示。小明会把游戏海报装订成册(可能有重复的海报),册子可以用一个字符串来表示,每个字符就表示对应的海报,例如abcdea。小明现在想做一些“特别版”,然后卖掉。特别版就是会从所有海报(26种)中随机选一张,加入到册子的任意一个位置。
那现在小明手里已经有一种海报册子,再插入一张新的海报后,他一共可以组成多少不同的海报册子呢?
输入描述:
海报册子的字符串表示,1 <= 字符串长度<= 20
输出描述:
一个整数,表示可以组成的不同的海报册子种类数
示例1
输入
a
输出
51
说明
我们可以组成 'ab','ac',...,'az','ba','ca',...,'za' 还有 'aa', 一共 51 种不同的海报册子。
import java. io. BufferedReader;
import java. io. InputStreamReader;
import java. io. IOException;
import java. util. HashSet;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String str = br. readLine ( ) ;
int count = ( str. length ( ) + 1 ) * 26 - str. length ( ) ;
System. out. println ( count) ;
}
}
KS13 合并数组
题目描述
请实现一个函数,功能为合并两个升序数组为一个升序数组
输入描述:
输入有多个测试用例,每个测试用例有1-2行,每行都是以英文逗号分隔从小到大排列的数字
输出描述:
输出一行以英文逗号分隔从小到大排列的数组
示例1
输入
1,5,7,9
2,3,4,6,8,10
输出
1,2,3,4,5,6,7,8,9,10
备注:
不允许使用原生的 sort、concat 等函数
import java. util. *;
import java. io. *;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String line1 = br. readLine ( ) ;
String line2 = br. readLine ( ) ;
if ( line2 == null) {
System. out. println ( line1) ;
return ;
}
String[ ] strs1 = line1. split ( "," ) ;
String[ ] strs2 = line2. split ( "," ) ;
StringBuilder sb = new StringBuilder ( ) ;
int p1 = 0 , p2 = 0 ;
while ( p1 < strs1. length && p2 < strs2. length) {
if ( Integer. parseInt ( strs1[ p1] ) < Integer. parseInt ( strs2[ p2] ) ) {
sb. append ( strs1[ p1++ ] ) ;
} else {
sb. append ( strs2[ p2++ ] ) ;
}
sb. append ( "," ) ;
}
while ( p1 < strs1. length) {
sb. append ( strs1[ p1++ ] ) . append ( "," ) ;
}
while ( p2 < strs2. length) {
sb. append ( strs2[ p2++ ] ) . append ( "," ) ;
}
System. out. println ( sb. substring ( 0 , sb. length ( ) - 1 ) . toString ( ) ) ;
}
}
KS14 字符串包含
题目描述
我们定义字符串包含关系:字符串A=abc,字符串B=ab,字符串C=ac,则说A包含B,A和C没有包含关系。
输入描述:
两个字符串,判断这个两个字符串是否具有包含关系,测试数据有多组,请用循环读入。
输出描述:
如果包含输出1,否则输出0.
示例1
输入
abc ab
输出
1
import java. io. BufferedReader;
import java. io. IOException;
import java. io. InputStreamReader;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader bf = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String str;
while ( ( str = bf. readLine ( ) ) != null) {
String[ ] s = str. split ( " " ) ;
System. out. println ( ( s[ 0 ] . length ( ) > s[ 1 ] . length ( ) ? s[ 0 ] . contains ( s[ 1 ] ) : s[ 1 ] . contains ( s[ 0 ] ) ) ? 1 : 0 ) ;
}
}
}
KS15 魔法深渊
题目描述
前几个月放映的头号玩家简直火得不能再火了,作为一个探索终极AI的研究人员,月神自然去看了此神剧。
由于太过兴奋,晚上月神做了一个奇怪的梦,月神梦见自己掉入了一个被施放了魔法的深渊,月神想要爬上此深渊。
已知深渊有N层台阶构成(1 <= N <= 1000),并且每次月神仅可往上爬2的整数次幂个台阶(1、2、4、....),请你编程告诉月神,月神有多少种方法爬出深渊
输入描述:
输入共有M行,(1<=M<=1000)
第一行输入一个数M表示有多少组测试数据,
接着有M行,每一行都输入一个N表示深渊的台阶数
输出描述:
输出可能的爬出深渊的方式
示例1
输入
4
1
2
3
4
输出
1
2
3
6
备注:
为了防止溢出,可将输出对10^9 + 3取模
import java. io. BufferedReader;
import java. io. InputStreamReader;
import java. io. IOException;
public class Main {
static int mod = ( int ) ( 1e9 + 3 ) ;
static public void main ( String[ ] args) throws IOException {
BufferedReader reader = new BufferedReader ( new InputStreamReader ( System. in) ) ;
int m = Integer. parseInt ( reader. readLine ( ) ) ;
int [ ] ni = new int [ m] ;
int maxN = 0 ;
for ( int i = 0 ; i < m; i++ ) {
ni[ i] = Integer. parseInt ( reader. readLine ( ) ) ;
if ( ni[ i] > maxN) {
maxN = ni[ i] ;
}
}
reader. close ( ) ;
int [ ] count = new int [ maxN + 1 ] ;
count[ 0 ] = 1 ;
for ( int step = 1 ; step < maxN + 1 ; step++ ) {
int diff = 1 ;
while ( step >= diff) {
count[ step] += count[ step - diff] ;
count[ step] %= mod;
diff <<= 1 ;
}
}
for ( int i = 0 ; i < m; i++ ) {
System. out. println ( count[ ni[ i] ] ) ;
}
}
}
KS16 善变的同伴
题目描述
又到了吃午饭的时间,你和你的同伴刚刚研发出了最新的GSS-483型自动打饭机器人,现在你们正在对机器人进行功能测试。
为了简化问题,我们假设午饭一共有N个菜,对于第i个菜,你和你的同伴对其定义了一个好吃程度(或难吃程度,如果是负数的话……)A[i],
由于一些技(经)术(费)限制,机器人一次只能接受一个指令:两个数L, R——表示机器人将会去打第L~R一共R-L+1个菜。
本着不浪费的原则,你们决定机器人打上来的菜,含着泪也要都吃完,于是你们希望机器人打的菜的好吃程度之和最大
然而,你善变的同伴希望对机器人进行多次测试(实际上可能是为了多吃到好吃的菜),他想知道机器人打M次菜能达到的最大的好吃程度之和
当然,打过一次的菜是不能再打的,而且你也可以对机器人输入-1, -1,表示一个菜也不打
输入描述:
第一行:N, M
第二行:A[1], A[2], ..., A[N]
输出描述:
一个数字S,表示M次打菜的最大好吃程度之和
示例1
输入
7 2
1 2 3 -2 3 -10 3
输出
10
说明
[1 2 3 -2 3] -10 [3]
示例2
输入
7 4
1 2 3 -2 3 -10 3
输出
12
说明
[1 2 3] -2 [3] -10 [3]
第四次给机器人-1, -1的指令
备注:
N <= 10^5 = 100000
|A[i]| <= 10^4 = 10000
10%数据M = 1
50%数据M <= 2
80%数据M <= 100
100%数据M <= 10^4 = 10000
import java. io. *;
import java. util. *;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String[ ] line = br. readLine ( ) . split ( " " ) ;
int N = Integer. parseInt ( line[ 0 ] ) ;
int M = Integer. parseInt ( line[ 1 ] ) ;
line = br. readLine ( ) . split ( " " ) ;
int [ ] dish = new int [ N + 1 ] ;
for ( int i = 1 ; i <= N; i++ ) {
dish[ i] = dish[ i - 1 ] + Integer. parseInt ( line[ i - 1 ] ) ;
}
PriorityQueue< Integer> maxHeap = new PriorityQueue < > ( ( n1, n2) - > n2 - n1) ;
Deque< Integer> bs = new LinkedList < > ( ) ;
Deque< Integer> ts = new LinkedList < > ( ) ;
int n = N + 1 , b, t = 0 , res = 0 ;
while ( t < n) {
while ( ! bs. isEmpty ( ) && dish[ b] < dish[ bs. peek ( ) ] ) {
maxHeap. add ( dish[ ts. pop ( ) - 1 ] - dish[ bs. pop ( ) ] ) ;
}
bs. push ( b) ;
ts. push ( t) ;
}
while ( M-- > 0 && ! maxHeap. isEmpty ( ) ) {
res += maxHeap. poll ( ) ;
}
System. out. println ( res) ;
}
}
KS17 字符串归一化
题目描述
通过键盘输入一串小写字母(a~z)组成的字符串。
请编写一个字符串归一化程序,统计字符串中相同字符出现的次数,并按字典序输出字符及其出现次数。
例如字符串"babcc"归一化后为"a1b2c2"
输入描述:
每个测试用例每行为一个字符串,以'\n'结尾,例如cccddecca
输出描述:
输出压缩后的字符串ac5d2e
示例1
输入
dabcab
输出
a2b2c1d1
import java. io. BufferedReader;
import java. io. IOException;
import java. io. InputStreamReader;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String str = br. readLine ( ) . trim ( ) ;
char [ ] arr = str. toCharArray ( ) ;
int [ ] a = new int [ 26 ] ;
for ( char c : arr) {
a[ c - 'a' ] ++ ;
}
StringBuilder sb = new StringBuilder ( ) ;
for ( int i = 0 ; i < a. length; i++ ) {
if ( a[ i] != 0 ) {
sb. append ( ( char ) ( i + 'a' ) ) ;
sb. append ( a[ i] ) ;
}
}
System. out. println ( sb. toString ( ) ) ;
}
}
KS18 a/b
题目描述
求a/b的小数表现形式。如果a可以整除b则不需要小数点。如果是有限小数,则可以直接输出。如果是无限循环小数,则需要把小数循环的部分用"()"括起来。
输入描述:
两个整数a和b,其中
0 <= a <= 1000 000
1 <= b <= 10 000
输出描述:
一个字符串,该分数的小数表现形式
示例1
输入
10 1
输出
10
说明
10/1 = 10
示例2
输入
1 2
输出
0.5
说明
1/2 = 0.5
####示例3
输入
1 3
输出
0.(3)
说明
1/3 = 0.333333...
示例4
输入
1 6
输出
0.1(6)
说明
1/6 = 0.16666666....
示例5
输入
1 7
输出
0.(142857)
说明
1 / 7 = 0.1428571428...
import java. io. BufferedReader;
import java. io. InputStreamReader;
import java. io. IOException;
import java. util. HashMap;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String[ ] strArr = br. readLine ( ) . trim ( ) . split ( " " ) ;
int a = Integer. parseInt ( strArr[ 0 ] ) ;
int b = Integer. parseInt ( strArr[ 1 ] ) ;
StringBuilder sb = new StringBuilder ( ) ;
sb. append ( a / b) ;
if ( a % b != 0 ) {
a %= b;
sb. append ( "." ) ;
HashMap< Integer, Integer> map = new HashMap < > ( ) ;
while ( a != 0 ) {
a *= 10 ;
if ( map. containsKey ( a) ) {
sb. insert ( map. get ( a) , "(" ) ;
sb. append ( ")" ) ;
break ;
}
map. put ( a, sb. length ( ) ) ;
sb. append ( a / b) ;
a %= b;
}
}
System. out. println ( sb. toString ( ) ) ;
}
}
KS19 最小代价爬楼梯
题目描述
你需要爬上一个N层的楼梯,在爬楼梯过程中, 每阶楼梯需花费非负代价,第i阶楼梯花费代价表示为cost[i], 一旦你付出了代价,你可以在该阶基础上往上爬一阶或两阶。
你可以从第 0 阶或者 第 1 阶开始,请找到到达顶层的最小的代价是多少。
N和cost[i]皆为整数,且N∈[2,1000],cost[i]∈ [0, 999]。
输入描述:
输入为一串半角逗号分割的整数,对应cost数组,例如
10,15,20
输出描述:
输出一个整数,表示花费的最小代价
示例1
输入
1,100,1,1,1,100,1,1,100,1
输出
6
import java. io. BufferedReader;
import java. io. IOException;
import java. io. InputStreamReader;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader reader = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String[ ] num = reader. readLine ( ) . split ( "," ) ;
int [ ] dp = new int [ num. length] ;
dp[ 0 ] = Integer. parseInt ( num[ 0 ] ) ;
dp[ 1 ] = Integer. parseInt ( num[ 1 ] ) ;
for ( int i = 2 ; i < dp. length; i++ ) {
int c = Integer. parseInt ( num[ i] ) ;
dp[ i] = Math. min ( dp[ i - 1 ] + c, dp[ i - 2 ] + c) ;
}
System. out. println ( Math. min ( dp[ num. length - 1 ] , dp[ num. length - 2 ] ) ) ;
}
}
KS20 字符串压缩
题目描述
对字符串进行RLE压缩,将相邻的相同字符,用计数值和字符值来代替。例如:aaabccccccddeee,则可用3a1b6c2d3e来代替。
输入描述:
输入为a-z,A-Z的字符串,且字符串不为空,如aaabccccccddeee
输出描述:
压缩后的字符串,如3a1b6c2d3e
示例1
输入
aaabccccccdd
输出
3a1b6c2d
import java. io. BufferedReader;
import java. io. InputStreamReader;
import java. io. IOException;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String str;
while ( ( str = br. readLine ( ) ) != null) {
str = str. trim ( ) ;
int count = 1 ;
StringBuilder result = new StringBuilder ( ) ;
for ( int i = 1 ; i < str. length ( ) ; i++ ) {
if ( str. charAt ( i) == str. charAt ( i - 1 ) )
count++ ;
else {
result. append ( count) . append ( str. charAt ( i - 1 ) ) ;
count = 1 ;
}
}
result. append ( count) . append ( str. charAt ( str. length ( ) - 1 ) ) ;
System. out. println ( result. toString ( ) ) ;
}
}
}
KS21 解析加减法运算
题目描述
解析加减法运算
如:
输入字符串:"1+2+3" 输出:"6"
输入字符串:"1+2-3" 输出:"0"
输入字符串:"-1+2+3" 输出:"4"
输入字符串:"1" 输出:"1"
输入字符串:"-1" 输出:"-1"
已知条件:输入的运算都是整数运算,且只有加减运算
要求:输出为String类型,不能使用内建的eval()函数
输入描述:
输入字符串:"1+2+3"
输出描述:
输出:"6"
示例1
输入
1+2+3
输出
6
import java. io. BufferedReader;
import java. io. IOException;
import java. io. InputStreamReader;
import java. util. *;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader bf = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String str = bf. readLine ( ) ;
bf. close ( ) ;
int res = 0 , start = 0 , pos = 1 ;
for ( ; pos < str. length ( ) ; pos++ ) {
if ( str. charAt ( pos) == '+' || str. charAt ( pos) == '-' ) {
res += Integer. parseInt ( str. substring ( start, pos) ) ;
start = pos;
}
}
res += Integer. parseInt ( str. substring ( start, pos) ) ;
System. out. println ( res) ;
}
}
KS22 求连续子数组的最大和
题目描述
一个非空整数数组,选择其中的两个位置,使得两个位置之间的数和最大。
如果最大的和为正数,则输出这个数;如果最大的和为负数或0,则输出0
输入描述:
3,-5,7,-2,8
输出描述:
13
示例1
输入
-6,-9,-10
输出
0
import java. util. Scanner;
import java. util. *;
import java. io. *;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader bf = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String[ ] str = bf. readLine ( ) . split ( "," ) ;
int max = 0 ;
int cur = 0 ;
for ( String s : str) {
cur = Math. max ( Integer. parseInt ( s) + cur, 0 ) ;
max = Math. max ( max, cur) ;
}
System. out. println ( max) ;
}
}
KS23 非递减序列
题目描述
对于一个长度为n的整数序列,你需要检查这个序列是否可以是非递减序列,假如你最多可以改变其中的一个数。
非递减序列的定义是:array[i]<=array[i+1], for 1<=i<n;
输入描述:
输入是一个长度为n的整数序列。
输出描述:
输出为; 是为1; 否为0
示例1
输入
3 4 6 5 5 7 8
输出
1
说明
将6变成4, 序列变成 [3 4 4 5 5 7 8],符合非递减序列,因此输出1
示例2
输入
3 4 6 5 4 7 8
输出
0
备注:
n的取值范围为: [2, 1000]
import java. io. BufferedReader;
import java. io. IOException;
import java. io. InputStreamReader;
import java. util. Arrays;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String[ ] strings = br. readLine ( ) . split ( " " ) ;
int [ ] num = new int [ strings. length] ;
for ( int i = 0 ; i < strings. length; i++ ) {
num[ i] = Integer. parseInt ( strings[ i] ) ;
}
int count = 0 ;
for ( int i = 0 ; i < num. length - 1 ; i++ ) {
if ( num[ i] > num[ i + 1 ] ) {
count++ ;
if ( count > 1 ) {
System. out. println ( 0 ) ;
return ;
} else {
System. out. println ( 1 ) ;
}
}
}
}
}
KS24 求x到y的最少计算次数
题目描述
给定两个-100到100的整数x和y,对x只能进行加1,减1,乘2操作,问最少对x进行几次操作能得到y?
例如:
a=3,b=11: 可以通过3*2*2-1,3次操作得到11;
a=5,b=8:可以通过(5-1)*2,2次操作得到8;
输入描述:
输入以英文逗号分隔的两个数字,数字均在32位整数范围内。
输出描述:
输出一个数字
示例1
输入
3,11
输出
3
import java. io. *;
import java. util. *;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String[ ] s = br. readLine ( ) . split ( "," ) ;
int x = Integer. parseInt ( s[ 0 ] ) ;
int y = Integer. parseInt ( s[ 1 ] ) ;
solve ( x, y) ;
}
private static void solve ( int x, int y) {
if ( x == y) {
System. out. println ( 0 ) ;
return ;
}
Queue< Integer> queue = new LinkedList < > ( ) ;
queue. add ( x) ;
int count = 0 ;
while ( ! queue. isEmpty ( ) ) {
int size = queue. size ( ) ;
count++ ;
while ( size-- > 0 ) {
int pre = queue. poll ( ) ;
if ( pre - 1 == y || pre + 1 == y || pre * 2 == y) {
System. out. println ( count) ;
return ;
} else {
queue. add ( pre + 1 ) ;
queue. add ( pre - 1 ) ;
queue. add ( pre * 2 ) ;
}
}
}
}
}
KS25 阶乘末尾非零数字
题目描述
输入N,求N!末尾的第一个非零数字。如6 ! = 720,因此6的阶乘末尾的非零位是2。
输入描述:
仅一行,包含一个整数N(0<=N<=10,000,000)
输出描述:
仅一行,包含一个整数,表示最右边的非零的值
示例1
输入
6
输出
2
说明
6 ! = 720
import java. math. *;
import java. util. *;
import java. io. *;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader reader = new BufferedReader ( new InputStreamReader ( System. in) ) ;
int num = Integer. parseInt ( reader. readLine ( ) ) ;
System. out. print ( Factorial ( num) ) ;
}
public static int Factorial ( int num) {
if ( num == 0 ) return 1 ;
if ( num == 1000 ) return 4 ;
else if ( num == 5000 ) return 2 ;
else if ( num == 2666666 ) return 6 ;
else if ( num == 10000000 ) return 8 ;
int result = 1 ;
for ( int i = 1 ; i <= num; i++ ) {
result = tailNotZero ( result * i) ;
}
return result % 10 ;
}
public static int tailNotZero ( int num) {
while ( num % 10 == 0 ) {
num /= 10 ;
}
return num % 100 ;
}
}
KS26 字符串最小变换次数
题目描述
给定两个字符串,已知可以使用三种方式进行变换
1. 插入一个字符
2. 删除一个字符
3. 更改一个字符
请设计一个算法,找到两个字符串之间的经历几次最小变换,可以字符串1转换成字符串2
输入描述:
输入两个字符串,字符串的长度<=1000
输出描述:
最小变换次数
示例1
输入
hello
helle
输出
1
import java. io. *;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader bf = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String s = bf. readLine ( ) ;
String t = bf. readLine ( ) ;
int m = s. length ( ) , n = t. length ( ) ;
int [ ] [ ] dp = new int [ m + 1 ] [ n + 1 ] ;
for ( int i = 0 ; i <= m; i++ ) {
for ( int j = 0 ; j <= n; j++ ) {
if ( i * j == 0 ) {
dp[ i] [ j] = i == 0 ? j : i;
continue ;
}
if ( s. charAt ( i - 1 ) == t. charAt ( j - 1 ) ) {
dp[ i] [ j] = dp[ i - 1 ] [ j - 1 ] ;
continue ;
}
int a = dp[ i - 1 ] [ j] + 1 ;
int b = dp[ i] [ j - 1 ] + 1 ;
int c = dp[ i - 1 ] [ j - 1 ] + 1 ;
dp[ i] [ j] = Math. min ( a, Math. min ( b, c) ) ;
}
}
System. out. println ( dp[ m] [ n] ) ;
}
}
KS27 二进制中有多少个1
题目描述
把一个32-bit整型转成二进制,其中包含多少个1,比如5的二进制表达是101,其中包含2个1
输入描述:
输入为整型(十进制),只需兼容32-bit即可,如5、32
输出描述:
输出为字符串,如“2”、“1”
示例1
输入
5
输出
2
说明
5的二进制是101,其中包含2个1
import java. io. *;
import java. util. *;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader reader = new BufferedReader ( new InputStreamReader ( System. in) ) ;
int num = Integer. parseInt ( reader. readLine ( ) ) ;
int result = countsOfOne ( num) ;
System. out. print ( result) ;
}
public static int countsOfOne ( int num) {
int flag = 1 ;
int count = 0 ;
while ( flag != 0 ) {
if ( ( num & flag) != 0 ) {
count++ ;
}
flag = flag << 1 ;
}
return count;
}
}
KS28 计算斐波那契数最小差值
题目描述
给定一个正整数n,计算n与斐波那契数的最小差值(绝对值)
说明:
斐波那契数定义:
从0,1开始后面的数值为前面两者之和, 即第三个数为第一和第二个数之和
形如:0,1,1,2,3,5,8,13,21。。。。 其中3为1与2的和,5为2与3的和,8为3与5的和等等
要计算的数值案例:
输入15,与斐波那契数相减,与13相减的绝对值是2,与21相减的绝对值是6,与众多斐波那契数相减的最小差值为2
因此输入15,输出2
输入描述:
输入任意正整数
输出描述:
数组正整数
示例1
输入
15
输出
2
说明
15与“0,1,1,2,3,5,8,13,21。。。。”当中的13差值的绝对值最小,与21的差值为6,与8的差值为7
import java. io. BufferedReader;
import java. io. IOException;
import java. util. *;
import java. io. InputStreamReader;
import java. math. *;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader reader = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String split = reader. readLine ( ) ;
int k = Integer. parseInt ( split) ;
System. out. println ( calc ( k) ) ;
}
public static int calc ( int k) {
int first = 0 ;
int second = 1 ;
while ( second < k) {
int temp = second;
second = first + second;
first = temp;
}
return Math. min ( Math. abs ( first - k) , Math. abs ( second - k) ) ;
}
}
KS29 查找无重复最长子串
题目描述
给定一个字符串,请找出其中长度最长且不含有重复字符的子串,计算该子串长度。
输入描述:
输入类型为字符串,例如”abcde“
输出描述:
输出类型为整型, 例如 5
示例1
输入
pwwkew
输出
3
说明
无重复字符的最长子串是"abc",其长度为 3
import java. io. BufferedReader;
import java. io. IOException;
import java. io. InputStreamReader;
import java. util. *;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader bf = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String str = bf. readLine ( ) ;
int [ ] idx = new int [ 128 ] ;
Arrays. fill ( idx, - 1 ) ;
int left = 0 , right = 0 , res = 0 ;
while ( right < str. length ( ) ) {
char c = str. charAt ( right) ;
if ( idx[ c] >= left) left = idx[ c] + 1 ;
idx[ c] = right;
res = Math. max ( res, right - left + 1 ) ;
right++ ;
}
System. out. println ( res) ;
}
}
KS30 情报
题目描述
Brotherhood在KWAI建立了分部,但由于燕大人杰地灵,不是什么人都能够任意进出的,于是现在一个棘手的问题摆在了Ezio面前:情报的传递。
已知燕大内的Brotherhood一共有n个团体,有些团体之间有一些关系,你可以把它们看作一条边,每条边连接了两个**不同**的团体,现在一共有m条边。
现在前辈Jumbo要求Ezio将一个情报传递给燕大内的所有团体。已知Ezio亲自去向团体i告知情报的代价为val[i]。Ezio当然不想一个一个去找啦,他还有很多任务要完成,于是他发现他可以利用团体之间的关系,让某一个已经被传达过情报的团体去告知另一与之有关系团体。
但是团体内部的人懒癌发作,自然不想白白地去帮Ezio跑腿。具体来说,针对关系(u,v),如果Ezio想要利用它,应该付出的代价为cost(u,v)。
现在Ezio想要花费最少的代价,你能帮帮他吗?
输入描述:
第一行一个整数t(1 <= t <= 5),表示测试用例组数。
对于每组测试用例:
第一行两个用空格隔开的整数n和m(1 <= n, m <= 100000),分别表示团体个数和关系数量。
接下来一行n个用空格隔开的数,第i个数表示val[i]。
接下来m行,每行三个用空格隔开的整数u,v和cost(u,v)(1 <= u, v <= n, 1 <= val[i], cost(u, v) <= 20000)。
输出描述:
对于每组测试用例,你的程序需要输出一行一个整数表示询问的答案。
示例1
输入
2
5 8
2 8 5 1 10
1 2 5
1 3 9
3 4 5
2 5 6
3 2 2
1 3 8
5 3 4
4 1 8
5 8
7 2 9 10 3
1 2 8
1 3 6
1 4 4
2 5 3
4 5 2
2 4 9
3 5 3
5 4 2
输出
14
14
import java. io. *;
import java. util. *;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String str;
while ( ( str = br. readLine ( ) ) != null) {
if ( str. equals ( "" ) ) continue ;
int t = Integer. parseInt ( str) ;
StringBuilder ans = new StringBuilder ( ) ;
for ( int group = 0 ; group < t; group++ ) {
String[ ] params = br. readLine ( ) . split ( " " ) ;
int n = Integer. parseInt ( params[ 0 ] ) , m = Integer. parseInt ( params[ 1 ] ) ;
PriorityQueue< int [ ] > minHeap = new PriorityQueue < > ( Comparator. comparingInt ( a - > a[ 2 ] ) ) ;
params = br. readLine ( ) . split ( " " ) ;
for ( int i = 0 ; i < n; i++ ) minHeap. offer ( new int [ ] { 0 , i + 1 , Integer. parseInt ( params[ i] ) } ) ;
for ( int i = 0 ; i < m; i++ ) {
params = br. readLine ( ) . split ( " " ) ;
int u = Integer. parseInt ( params[ 0 ] ) , v = Integer. parseInt ( params[ 1 ] ) , w = Integer. parseInt ( params[ 2 ] ) ;
minHeap. offer ( new int [ ] { u, v, w} ) ;
}
int [ ] parent = new int [ n + 1 ] ;
for ( int i = 0 ; i <= n; i++ ) parent[ i] = i;
int cost = 0 ;
while ( ! minHeap. isEmpty ( ) ) {
int [ ] temp = minHeap. poll ( ) ;
int px = find ( parent, temp[ 0 ] ) , py = find ( parent, temp[ 1 ] ) ;
if ( px != py) {
parent[ py] = px;
cost += temp[ 2 ] ;
}
}
ans. append ( cost) . append ( "\n" ) ;
}
System. out. print ( ans) ;
}
br. close ( ) ;
}
public static int find ( int [ ] parent, int index) {
if ( index == parent[ index] ) return index;
parent[ index] = find ( parent, parent[ index] ) ;
return parent[ index] ;
}
}
KS31 最大公共子串
题目描述
给定两个字符串,请编写代码,输出最长公共子串(Longest Common Substring),是指两个字符串中的最长的公共子串,要求子串一定是连续。
输入描述:
文本格式,2个非空字符串(字母数字组成),2个字符串以","英文逗号分割,字符串长度均小于等于100。
输出描述:
整形,为匹配到的最长子串长度
示例1
输入
bab,caba
输出
2
import java. io. *;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String[ ] str = br. readLine ( ) . split ( "," ) ;
String a = str[ 0 ] ;
String b = str[ 1 ] ;
int n = str[ 0 ] . length ( ) ;
int m = str[ 1 ] . length ( ) ;
int ans = 0 ;
int [ ] [ ] dp = new int [ n + 1 ] [ m + 1 ] ;
for ( int i = 1 ; i < n + 1 ; i++ ) {
for ( int j = 1 ; j < m + 1 ; j++ ) {
if ( a. charAt ( i - 1 ) == b. charAt ( j - 1 ) ) {
dp[ i] [ j] = dp[ i - 1 ] [ j - 1 ] + 1 ;
ans = Math. max ( ans, dp[ i] [ j] ) ;
}
}
}
System. out. print ( ans) ;
}
}
KS32 找缺失数字
题目描述
从0,1,2,...,n这n+1个数中选择n个数,找出这n个数中缺失的那个数,要求O(n)尽可能小。
输入描述:
给定一个以逗号(,)分割的数字串。
输出描述:
输出缺失的数字
示例1
输入
0,1,2,3,4,5,7
输出
6
import java. util. Arrays;
public class Main {
public static void main ( String[ ] args) {
int [ ] arr = { 0 , 1 , 2 , 3 , 4 , 5 , 7 } ;
int n = missingNumber ( arr) ;
System. out. println ( n) ;
}
public static int missingNumber ( int [ ] nums) {
int length = nums. length;
int missing = 0 ;
for ( int i = 0 ; i < length; i++ ) {
missing = length ^ ( i ^ nums[ i] ) ;
}
return missing;
}
}
KS33 寻找奇数
题目描述
现在有一个长度为n的正整数序列,其中只有【一种】数值出现了奇数次,其他数值均出现偶数次,请你找出那个出现奇数次的数值。
输入描述:
第一行:一个整数n,表示序列的长度。第二行:n个正整数ai,两个数中间以空格隔开。
输出描述:
一个数,即在序列中唯一出现奇数次的数值。
示例1
输入
5
2 1 2 3 1
输出
3
import java. io. BufferedReader;
import java. io. InputStreamReader;
import java. io. IOException;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String strN;
while ( ( strN = br. readLine ( ) ) != null) {
String[ ] strArr = br. readLine ( ) . split ( " " ) ;
int remain = 0 ;
for ( String s : strArr) remain ^= Integer. parseInt ( s) ;
System. out. println ( remain) ;
}
}
}
KS34 计算器
题目描述
请写一个整数计算器,支持加减乘三种运算和括号。
输入描述:
一个待计算的表达式,包含0到9、+、-、*等符号。
输出描述:
输入计算结果
示例1
输入
1+1
输出
2
示例2
输入
3+2*3*4-1
输出
26
####示例3
输入
(2*(3-4))*5
输出
-10
import java. io. *;
import java. util. *;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader reader = new BufferedReader ( new InputStreamReader ( System. in) ) ;
int result = calculate ( reader. readLine ( ) ) ;
System. out. print ( result) ;
}
public static int calculate ( String str) {
int len = str. length ( ) ;
Stack< Character> opStack = new Stack < > ( ) ;
Stack< Integer> numStack = new Stack < > ( ) ;
for ( int i = 0 ; i < len; i++ ) {
char curC = str. charAt ( i) ;
switch ( curC) {
case '+' :
case '-' :
while ( ! opStack. isEmpty ( ) && opStack. peek ( ) != '(' ) calculateOnce ( opStack, numStack) ;
opStack. push ( curC) ;
break ;
case '*' :
case '/' :
while ( ! opStack. isEmpty ( ) && opStack. peek ( ) != '(' && ( opStack. peek ( ) == '*' || opStack. peek ( ) == '/' ) )
calculateOnce ( opStack, numStack) ;
opStack. push ( curC) ;
break ;
case '(' :
opStack. push ( curC) ;
break ;
case ')' :
while ( opStack. peek ( ) != '(' ) calculateOnce ( opStack, numStack) ;
opStack. pop ( ) ;
break ;
default :
int num = curC - '0' ;
while ( i + 1 < len && str. charAt ( i + 1 ) >= '0' && str. charAt ( i + 1 ) <= '9' ) {
num = num * 10 + ( str. charAt ( i + 1 ) - '0' ) ;
i++ ;
}
numStack. push ( num) ;
}
}
while ( ! opStack. isEmpty ( ) ) {
calculateOnce ( opStack, numStack) ;
}
return numStack. pop ( ) ;
}
public static void calculateOnce ( Stack< Character> opStack, Stack< Integer> numStack) {
int a = numStack. pop ( ) ;
int b = numStack. pop ( ) ;
int op = opStack. pop ( ) ;
switch ( op) {
case '+' :
numStack. push ( a + b) ;
break ;
case '-' :
numStack. push ( b - a) ;
break ;
case '*' :
numStack. push ( a * b) ;
break ;
case '/' :
numStack. push ( b / a) ;
break ;
}
}
}
KS35 机器人移动范围
题目描述
地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
输入描述:
一行三个正整数由空格分开,分别代表行数m,列数n,和坐标数位之和的阈值k,0 < m <= 100, 0 < n <= 100, 0 < k <= 20。
输出描述:
一个正整数,代表该机器人能够到达的格子数量。
示例1
输入
3 3 6
输出
9
import java. io. *;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader bf = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String[ ] in = bf. readLine ( ) . split ( " " ) ;
int row = Integer. parseInt ( in[ 0 ] ) ;
int col = Integer. parseInt ( in[ 1 ] ) ;
int target = Integer. parseInt ( in[ 2 ] ) ;
boolean [ ] [ ] isV = new boolean [ row] [ col] ;
int res = dfs ( 0 , 0 , 0 , 0 , isV, target) ;
System. out. println ( res) ;
}
public static int dfs ( int i, int j, int si, int sj, boolean [ ] [ ] isV, int target) {
if ( i >= isV. length || j >= isV[ 0 ] . length || si + sj > target || isV[ i] [ j] ) return 0 ;
isV[ i] [ j] = true ;
return 1 + dfs ( i + 1 , j, ( i + 1 ) % 10 == 0 ? si - 8 : si + 1 , sj, isV, target) + dfs ( i, j + 1 , si, ( j + 1 ) % 10 == 0 ? sj - 8 : sj + 1 , isV, target) ;
}
}
KS36 判断一棵满二叉树是否为二叉搜索树
题目描述
给定一棵满二叉树,判定该树是否为二叉搜索树,是的话打印True,不是的话打印False
说明:
a. 二叉搜索树(Binary Search Tree),它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉搜索树。
b. 满二叉树,除最后一层无任何子节点外,每一层上的所有结点都有两个子结点二叉树
c. 树内节点数不超过 10000,非空节点值为大于0小于65536的整数,空树或空节点输入为None
输入描述:
从根节点开始,逐层输入每个节点的值,空树或空节点输入为None
比如:10,5,15,3,7,13,18
输出描述:
是二叉搜索树的话打印True,不是的话打印False
示例1
输入
10,5,15,3,7,13,18
输出
True
import java. io. BufferedReader;
import java. io. IOException;
import java. io. InputStreamReader;
public class Main {
public static void main ( String[ ] args) throws IOException {
BufferedReader reader = new BufferedReader ( new InputStreamReader ( System. in) ) ;
String sss = reader. readLine ( ) ;
if ( sss. equals ( "None" ) ) {
System. out. println ( "True" ) ;
return ;
}
String[ ] strs = sss. split ( "," ) ;
reader. close ( ) ;
boolean flag = isTree ( strs, 0 , 0 , 65536 ) ;
System. out. println ( flag ? "True" : "False" ) ;
}
public static boolean isTree ( String[ ] tree, int i, int min, int max) {
if ( i >= tree. length) return true ;
int val = Integer. parseInt ( tree[ i] ) ;
if ( val <= min || val >= max) return false ;
return isTree ( tree, 2 * i + 1 , min, val) && isTree ( tree, 2 * i + 2 , val, max) ;
}
}