概述
提示:本文所有的答案均是借鉴牛客网的大神们的解决方法(我只是个搬运工)
牛客网华为机考
- 一、入门
- 1.取近似值
- 2.提取不重复的整数
- 3.截取字符串
- 4.输入N个整数,输出其中最小的K个
- 5.输入整型数组和排序标识,对其元素按照升序或降序排列
- 二、简单
- 1.字符串最后一个单词的长度
- 2.计算某字符出现的次数
- 3.字符串分隔
- 4.进制转换
- 5.质数因子
- 6.合并表记录
- 7.字符个数统计
- 8.数字颠倒
- 9.字符串反转
- 10.句子逆序
- 11.字符串排序
- 12.求int型正整数在内存中存储时1的个数
- 13.简单密码
- 14.汽水瓶
- 15.删除字符串中出现次数最少的字符
- 16.单词倒排
- 17.图片整理
- 18.蛇形矩阵
- 19.统计每个月兔子总数
- 20.统计字符
- 21.输出单项链表中倒数第K个节点
- 22.杨辉三角的变形
- 23.表达式求值
- 24.完全数计算
- 25.查找组成一个偶数最接近的两个素数
- 26.放苹果
- 27.查找输入整数二进制中1的个数
- 28.百钱买鸡问题
- 29.计算日期到天数转换
- 30.尼科彻斯定理
- 31.整型数组合并
- 32.字符串字符匹配
- 33.二维数组操作
- 34.统计大写字母个数
- 35.最长回文子串
- 35.求最大连续bit数
- 36.密码强度等级
- 37.走方格的方案数
- 38.计票统计
- 39.表示数字
- 40.记负均正
- 41.自守数
- 42.等差数列
- 43.字符统计
- 44.记负均正||
- 45.字符逆序
- 46.求最小公倍数
- 三、中等
- 1.购物单
- 2.坐标移动
- 3.密码验证合格程序
- 4.合唱队
- 5.字符串排序
- 6.查找兄弟单词
- 7.字符串加密解密
- 8.密码截取
- 9.整数与IP地址之间的转换
- 10.字符串加密
- 11.求小球落地5次后经历的路程和第五次反弹的高度
- 12.称砝码
- 13.迷宫问题
- 14.名字的漂亮度
- 15.从单向链表中删除指定值的节点
- 16.四则运算
- 17.计算字符串的编辑距离
- 18.挑7
- 19.高精度整数加法
- 20.找出字符串中第一个只出现一次的字符
- 21.DNA序列
- 22.MP3光标位置
- 23.查找两个字符串a,b中最长的公共子串
- 24.配置文件恢复
- 25.24点游戏算法
- 26.矩阵乘法
- 27.矩阵乘法计算量估算
- 28.字符串通配符
- 29.参数解析
- 30.公共子串计算
- 31.火车进站
- 32.将真分数分解为埃及分数
- 33.合法IP
- 34.字符串中找出连续最长的数字串
- 35.Redraiment的走法
- 35.求解立方根
- 四、较难
- 1.明明的随机数
- 2.识别有效ip地址和掩码进行分类统计
- 3.简单错误记录
- 4.数据分类处理
- 5.字符串合并处理
- 6.判断两个IP是否属于同一子网
- 7.学英语
- 8.成绩排序
- 9.整数与IP地址之间的转换
- 10.扑克牌大小
- 11.24点运算
- 12.数组分组
- 13.人民币转换
- 五、困难
- 1.素数伴侣
- 2.sudoku
- 3.自动售货系统
提示:以下是本篇文章正文内容,下面案例可供参考
一、入门
1.取近似值
// 处理输入
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
Double integer = Double.valueOf(s);
//四舍五入
long round = Math.round(integer);
System.out.println(round);
2.提取不重复的整数
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
String resout="";
for (int i = s.length(); i >0 ; i--) {
if(!resout.contains(s.substring(i-1,i))){
resout=resout+s.substring(i-1,i);
}
}
System.out.println(Long.parseLong(resout));
3.截取字符串
4.输入N个整数,输出其中最小的K个
5.输入整型数组和排序标识,对其元素按照升序或降序排列
二、简单
1.字符串最后一个单词的长度
public static void sjs(){
Scanner scanner = new Scanner(System.in);
String next = scanner.nextLine();
int last = next.lastIndexOf(" ");
String substring = next.substring(last);
int length = substring.length();
System.out.println(length);
}
2.计算某字符出现的次数
public static void cout(){
Scanner scanner = new Scanner(System.in);
String ont = scanner.nextLine().toLowerCase();
char c = scanner.nextLine().toLowerCase().charAt(0);
int count =0;
for (int i = 0; i < ont.length(); i++) {
if(c==ont.charAt(i)){
count++;
}
}
System.out.println(count);
}
3.字符串分隔
public static void fg(){
Scanner scanner = new Scanner(System.in);
String one = scanner.nextLine();
int length = one.length();
if(length>8){
System.out.println(one.substring(0,8));
one=one.substring(8);
}else{
one=one+"00000000";
System.out.println(one.substring(0,8));
}
}
4.进制转换
Scanner input = new Scanner(System.in);
while(input.hasNextLine()){
String s = input.nextLine();
String substring = s.substring(2);
Integer integer = Integer.valueOf(substring,16);
System.out.println(integer);
}
5.质数因子
描述
功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如180的质因子为2 2 3 3 5 )
数据范围: 1 le n le 2 times 10^{9} + 14 1≤n≤2×10
9
+14
输入描述:
输入一个整数
输出描述:
按照从小到大的顺序输出它的所有质数的因子,以空格隔开。
示例1
输入:
180
复制
输出:
2 2 3 3 5
public class Main {
public static void main(String[] args) throws IOException {
// 处理输入
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
// 获取需要求解的值
int target = sc.nextInt();
int y = 2;// 因子从2开始算
while(target != 1){ // 短除法,除到目标值为1为止
if(target % y == 0) // 取模能能够整除2
{
System.out.print(y+" ");
target = target/y;
}else{// 更新y的值
if(y > target / y) {
y = target;//如果剩余值为质数
}
else y++; //y值增加1
}
}
}
}
}
6.合并表记录
数据表记录包含表索引index和数值value(int范围的正整数),请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照index值升序进行输出
提示:
0 <= index <= 11111111
1 <= value <= 100000
输入描述:
先输入键值对的个数n(1 <= n <= 500)
接下来n行每行输入成对的index和value值,以空格隔开
输出描述:
输出合并后的键值对(多行)
Scanner sc = new Scanner(System.in);
TreeMap<Integer,Integer> map = new TreeMap<>();
while(sc.hasNext()){
int n = sc.nextInt();
for(int i =0;i<n;i++){
int key = sc.nextInt();
int value = sc.nextInt();
map.put(key,map.getOrDefault(key,0)+value);//map.getOrDefault(key,0)如果用key找不到记录则返回0,找到就返货key对应的value
}
for(Integer i : map.keySet()){
System.out.println(i+" "+map.get(i));
}
}
7.字符个数统计
描述
编写一个函数,计算字符串中含有的不同字符的个数。字符在 ASCII 码范围内( 0~127 ,包括 0 和 127 ),换行表示结束符,不算在字符里。不在范围内的不作统计。多个相同的字符只计算一次
例如,对于字符串 abaca 而言,有 a、b、c 三种不同的字符,因此输出 3 。
数据范围: 1 le n le 500 1≤n≤500
输入描述:
输入一行没有空格的字符串。
输出描述:
输出 输入字符串 中范围在(0~127,包括0和127)字符的种数。
示例1
输入:
abc
输出:
3
示例2
输入:
aaa
输出:
1
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
char[] chars = s.toCharArray();
HashSet<Object> objects = new HashSet<>();
for (char aChar : chars) {
if(Integer.valueOf(aChar)>127){
continue;
}
objects.add(aChar);
}
System.out.println(objects.size());
8.数字颠倒
描述
输入一个整数,将这个整数以字符串的形式逆序输出
程序不考虑负数的情况,若数字含有0,则逆序形式也含有0,如输入为100,则输出为001
数据范围: 0 le n le 2^{30}-1 ≤n≤2
30
−1
输入描述:
输入一个int整数
输出描述:
将这个整数以字符串的形式逆序输出
示例1
输入:
1516000
输出:
0006151
示例2
输入:
0
输出:
0
import java.io.IOException;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
StringBuffer stringBuffer = new StringBuffer(s);
StringBuffer reverse = stringBuffer.reverse();
System.out.println(reverse);
}
}
9.字符串反转
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
StringBuffer stringBuffer = new StringBuffer(s);
StringBuffer reverse = stringBuffer.reverse();
System.out.println(reverse);
10.句子逆序
描述
将一个英文语句以单词为单位逆序排放。例如“I am a boy”,逆序排放后为“boy a am I”
所有单词之间用一个空格隔开,语句中除了英文字母外,不再包含其他字符
数据范围:输入的字符串长度满足 1 le n le 1000 1≤n≤1000
注意本题有多组输入
输入描述:
输入一个英文语句,每个单词用空格隔开。保证输入只包含空格和字母。
输出描述:
得到逆序的句子
示例1
输入:
I am a boy
输出:
boy a am I
示例2
输入:
nowcoder
输出:
nowcoder
public class Main {
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
String[] s1 = s.split(" ");
int length = s1.length;
for (int i = length-1; i >=0 ; i--) {
System.out.print(s1[i]+" ");
}
}
}
11.字符串排序
描述
给定 n 个字符串,请对 n 个字符串按照字典序排列。
数据范围: 1 le n le 1000 1≤n≤1000 ,字符串长度满足 1 le len le 100 1≤len≤100
输入描述:
输入第一行为一个正整数n(1≤n≤1000),下面n行为n个字符串(字符串长度≤100),字符串中只含有大小写字母。
输出描述:
数据输出n行,输出结果为按照字典序排列的字符串。
示例1
输入:
9
cap
to
cat
card
two
too
up
boat
boot
输出:
boat
boot
cap
card
cat
to
too
two
up
public static void main(String[] args) throws Exception{
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String[] strings = new String[n]; //创建一个字符串数组
for (int j = 0; j < n; j++) {
//不接受空格回车
strings[j]=sc.next();
}
Arrays.sort(strings);
for (String string : strings) {
System.out.println(string);
}
}
12.求int型正整数在内存中存储时1的个数
描述
输入一个 int 型的正整数,计算出该 int 型数据在内存中存储时 1 的个数。
数据范围:保证在 32 位整型数字范围内
输入描述:
输入一个整数(int类型)
输出描述:
这个数转换成2进制后,输出1的个数
示例1
输入:
5
复制
输出:
2
复制
示例2
输入:
0
复制
输出:
0
import java.io.InputStream;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int number = sc.nextInt();
String s = Integer.toString(number, 2).replaceAll("0", "");//转成二进制字符串
String s1 = s.replaceAll("0", "");//所有的0去除
System.out.println(s1.length());
}
}
}
13.简单密码
描述
现在有一种密码变换算法。
九键手机键盘上的数字与字母的对应: 1–1, abc–2, def–3, ghi–4, jkl–5, mno–6, pqrs–7, tuv–8 wxyz–9, 0–0,把密码中出现的小写字母都变成九键键盘对应的数字,如:a 变成 2,x 变成 9.
而密码中出现的大写字母则变成小写之后往后移一位,如:X ,先变成小写,再往后移一位,变成了 y ,例外:Z 往后移是 a 。
数字和其它的符号都不做变换。
数据范围: 输入的字符串长度满足 1 le n le 100 1≤n≤100
输入描述:
输入一组密码,长度不超过100个字符。
输出描述:
输出密码变换后的字符串
示例1
输入:
YUANzhi1987
复制
输出:
zvbo9441987
import java.util.*;
public class Main {
//定义map容器存储按键对应数字字符的容器
private static Map<String,String> map = new HashMap<>();
//静态初始化、加载map容器
static{
map.put("1","1");
map.put("abc","2");
map.put("def","3");
map.put("ghi","4");
map.put("jkl","5");
map.put("mno","6");
map.put("pqrs","7");
map.put("tuv","8");
map.put("wxyz","9");
map.put("0","0");
}
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
while(scanner.hasNext()){
String str = scanner.nextLine();
char[] chars = str.toCharArray();
//构造buffer容器存储转换后的字符串
StringBuffer buffer = new StringBuffer();
for(char c : chars){
//如果是正整数则不需要进行加密
if(c>='0'&& c<='9'){
buffer.append(String.valueOf(c));
}else if(c>='A'&& c<='Y'){ //如果是A~Y的大写字母则需要将其+32位转换成小写再向后移1位
char newChar = (char)(c+32+1);
buffer.append(String.valueOf(newChar));
}else if(c=='Z'){ //如果是Z则加密成a
buffer.append("a");
}else{
//去除map容器中的key与字符进行校验并加密
Set<String> keys = map.keySet();
for(String k : keys){
if(k.contains(String.valueOf(c)))
buffer.append(map.get(k));
}
}
}
System.out.print(buffer.toString());
}
}
}
14.汽水瓶
public static void hs() throws IOException {
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
BufferedReader bf = new BufferedReader(inputStreamReader);
String s=bf.readLine();
if(s!=null){
Integer integer = Integer.valueOf(s);
System.out.println(integer/2);
}
}
15.删除字符串中出现次数最少的字符
描述
实现删除字符串中出现次数最少的字符,若出现次数最少的字符有多个,则把出现次数最少的字符都删除。输出删除这些单词后的字符串,字符串中其它字符保持原来的顺序。
数据范围:输入的字符串长度满足 1 le n le 20 1≤n≤20 ,保证输入的字符串中仅出现小写字母
输入描述:
字符串只包含小写英文字母, 不考虑非法输入,输入的字符串长度小于等于20个字节。
输出描述:
删除字符串中出现次数最少的字符后的字符串。
示例1
输入:
aabcddd
复制
输出:
aaddd
import java.util.*;
import java.io.IOException;
public class Main{
public static void main(String[] args) throws Exception{
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String s = scanner.nextLine();
char[] chars = s.toCharArray();
//统计每个字母的数量
HashMap<Character, Integer> map = new HashMap<>();
for (char aChar : chars) {
map.put(aChar, (map.getOrDefault(aChar, 0) + 1));
}
//找到数量最少的字符数量
Collection<Integer> values = map.values();
Integer min = Collections.min(values);
//用空字符串替换该字母
for (Character character : map.keySet()) {
if (map.get(character) == min){
s = s.replaceAll(String.valueOf(character), "");
}
}
System.out.println(s);
}
}
}
16.单词倒排
描述
对字符串中的所有单词进行倒排。
说明:
1、构成单词的字符只有26个大写或小写英文字母;
2、非构成单词的字符均视为单词间隔符;
3、要求倒排后的单词间隔符以一个空格表示;如果原字符串中相邻单词间有多个间隔符时,倒排转换后也只允许出现一个空格间隔符;
4、每个单词最长20个字母;
数据范围:字符串长度满足 1 le n le 10000 1≤n≤10000
输入描述:
输入一行,表示用来倒排的句子
输出描述:
输出句子的倒排结果
示例1
输入:
I am a student
复制
输出:
student a am I
复制
示例2
输入:
$bo*y gi!r#l
复制
输出:
l r gi y bo
import java.io.IOException;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
Scanner scanner = new Scanner(System.in);
StringBuffer stringBuffer = new StringBuffer();
String s = scanner.nextLine();
String[] split = s.split("[^a-zA-Z]+");
for (int i = split.length - 1; i >= 0; i--){
stringBuffer.append(split[i] + " ");
}
System.out.println(stringBuffer);
}
}
17.图片整理
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.nextLine();
char[] chars = s.toCharArray();
Arrays.sort(chars);
System.out.println(chars);
}
}
描述
Lily上课时使用字母数字图片教小朋友们学习英语单词,每次都需要把这些图片按照大小(ASCII码值从小到大)排列收好。请大家给Lily帮忙,通过代码解决。
Lily使用的图片使用字符"A"到"Z"、“a"到"z”、"0"到"9"表示。
数据范围:每组输入的字符串长度满足 1 le n le 1000 1≤n≤1000
输入描述:
一行,一个字符串,字符串中的每个字符表示一张Lily使用的图片。
输出描述:
Lily的所有图片按照从小到大的顺序输出
示例1
输入:
Ihave1nose2hands10fingers
复制
输出:
0112Iaadeeefghhinnnorsssv
18.蛇形矩阵
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[][] a = new int[n][n];
//找出第一行的规律公式 (n+1)(n+2)/2;
for(int j=0;j<n;j++){
a[0][j] = (j+1)*(j+2)/2;//初始化第一行
}
for (int i = 1; i < n; i++) { //从第二行开始
for (int j = 0; j < n-1; j++) { //列
a[i][j] = a[i-1][j]+i+j; //a[i-1][j]获取当前列的前一列值 +i+j标识能持续+
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n-i; j++) {
System.out.print(a[i][j]+" ");
}
System.out.println("");//换行
}
}
}
19.统计每个月兔子总数
解法1:斐波那契数列 f(n) = f(n-1)+f(n-2)
public static int tz(int month){
if(month<3){
System.out.println(1);
return 1;
}else{
System.out.println(tz(month-2)+tz(month-1));
return tz(month-2)+tz(month-1);
}
}
解法二
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
//初始化第一个月
int oneMonth=1;
int twoMonth=0;
int threeMonth=0;// 三月龄及以上兔子总数
// 下个月将繁殖的兔子数量
int addVal = 0;
// 第二个月开始递推, i表示第i个月
for (int i = 2; i <= n; i++) {
// 三月龄及以上兔子总数 = 二月龄兔子总数 + 原本三月龄及以上兔子总数
threeMonth += twoMonth;
// 二月龄兔子总数 = 上个月的一月龄兔子总数
twoMonth = oneMonth;
// 一月龄(即这个月出生)兔子总数 = 上个月将繁殖的兔子数量
oneMonth = addVal;
// 下个月将出生的兔子 = 下个月成为三月龄及以上的兔子数量
addVal = twoMonth + threeMonth;
}
System.out.println(oneMonth + twoMonth + threeMonth);
}
}
20.统计字符
描述
输入一行字符,分别统计出包含英文字母、空格、数字和其它字符的个数。
数据范围:输入的字符串长度满足 1 le n le 1000 1≤n≤1000
输入描述:
输入一行字符串,可以有空格
输出描述:
统计其中英文字符,空格字符,数字字符,其他字符的个数
示例1
输入:
1qazxsw23 edcvfr45tgbn hy67uj m,ki89ol./;p0-=][
输出:
26
3
10
12
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String str = in.nextLine();
char[] chars = str.toCharArray();
int yw=0;
int kg=0;
int sz=0;
int qt=0;
for (char aChar : chars) {
if(Character.isLetter(aChar)){
yw++;
}else if ('0'<=aChar && aChar <='9'){
sz++;
}else if (aChar==' '){
kg++;
}else{
qt++;
}
}
System.out.println(yw);
System.out.println(kg);
System.out.println(sz);
System.out.println(qt);
}
}
21.输出单项链表中倒数第K个节点
描述
输入一个单向链表,输出该链表中倒数第k个结点,链表的倒数第1个结点为链表的尾指针。
链表结点定义如下:
struct ListNode
{
int m_nKey;
ListNode* m_pNext;
};
正常返回倒数第k个结点指针,异常返回空指针.
要求:
(1)正序构建链表;
(2)构建后要忘记链表长度。
数据范围:链表长度满足 1 le n le 1000 1≤n≤1000 , k le n k≤n ,链表中数据满足 0 le val le 10000 ≤val≤10000
本题有多组样例输入。
输入描述:
输入说明
1 输入链表结点个数
2 输入链表的值
3 输入k的值
输出描述:
输出一个整数
示例1
输入:
8
1 2 3 4 5 6 7 8
4
复制
输出:
5
22.杨辉三角的变形
以上三角形的数阵,第一行只有一个数1,以下每行的每个数,是恰好是它上面的数、左上角数和右上角的数,3个数之和(如果不存在某个数,认为该数就是0)。
求第n行第一个偶数出现的位置。如果没有偶数,则输出-1。例如输入3,则输出2,输入4则输出3,输入2则输出-1。
数据范围: 1 le n le 10^9 1≤n≤10
9
输入描述:
输入一个int整数
输出描述:
输出返回的int值
示例1
输入:
4
复制
输出:
3
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();//第n行有2n-1个数,且第N行的第2个数一定为(n-1)
if(n==1||n==2){
System.out.println(-1);
}else{
if(n%2!=0){ //n是奇数的时候,这一行的偶数一定在第二位
System.out.println(2);
}else{
if(n%4==0){ //n是偶数的时候,这一行的偶数出现要么在第三位,要么就是在第四位,并且能被四整除的时候就在第三位,不能就在第四位
System.out.println(3);
}else{
System.out.println(4);
}
}
}
}
}
23.表达式求值
描述
给定一个字符串描述的算术表达式,计算出结果值。
输入字符串长度不超过 100 ,合法的字符包括 ”+, -, *, /, (, )” , ”0-9” 。
数据范围:运算过程中和最终结果均满足 |val| le 2^{31}-1 ∣val∣≤2
31
−1 ,即只进行整型运算,确保输入的表达式合法
输入描述:
输入算术表达式
输出描述:
计算出结果值
示例1
输入:
400+5
复制
输出:
405
public class Main {
public static void main(String[] args) throws ScriptException {
Scanner in = new Scanner(System.in);
String s = in.nextLine();
//使用js的eval函数
ScriptEngine js = new ScriptEngineManager().getEngineByName("js");
System.out.println(js.eval(s));
}
}
24.完全数计算
描述
完全数(Perfect number),又称完美数或完备数,是一些特殊的自然数。
它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。
例如:28,它有约数1、2、4、7、14、28,除去它本身28外,其余5个数相加,1+2+4+7+14=28。
输入n,请输出n以内(含n)完全数的个数。
数据范围: 1 le n le 5 times 10^{5} 1≤n≤5×10
5
输入描述:
输入一个数字n
输出描述:
输出不超过n的完全数的个数
示例1
输入:
1000
复制
输出:
3
public class Main {
public static void main(String[] args) throws IOException {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int res = 0;
for (int i = 1; i <= n; i++) {
int sum = 0;
for (int j = 2; j <= i; j++) {
if (i % j == 0) {
sum = sum + (i / j);
//System.out.println(i+"的约数"+i/j);
}
}
//System.out.println(i+"的约数和"+sum);
if (sum == i) {
//System.out.println(i);
res++;
}
}
System.out.println(res);
}
}
25.查找组成一个偶数最接近的两个素数
描述
任意一个偶数(大于2)都可以由2个素数组成,组成偶数的2个素数有很多种情况,本题目要求输出组成指定偶数的两个素数差值最小的素数对。
数据范围:输入的数据满足 4 le n le 1000 4≤n≤1000
输入描述:
输入一个大于2的偶数
输出描述:
从小到大输出两个素数
示例1
输入:
20
复制
输出:
7
13
26.放苹果
27.查找输入整数二进制中1的个数
28.百钱买鸡问题
描述
公元五世纪,我国古代数学家张丘建在《算经》一书中提出了“百鸡问题”:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?
现要求你打印出所有花一百元买一百只鸡的方式。
输入描述:
输入任何一个整数,即可运行程序。
输出描述:
输出有数行,每行三个整数,分别代表鸡翁,母鸡,鸡雏的数量
示例1
输入:
1
复制
输出:
0 25 75
4 18 78
8 11 81
12 4 84
public class Main {
public static void main(String[] args) throws ScriptException {
Scanner in = new Scanner(System.in);
// 买x鸡翁,y只鸡母,z只鸡雏
//5x+3y+z/3=100 ==> 15x + 9y + z = 300
//x+y+z==100确定
// ==> 14x + 8y = 200 ==> 7x + 4y = 100 ==> y = (100 - 7x)/4
while (in.hasNextInt()){
int n = in.nextInt();
for (int x = 0; x <= 14; x++) {
if ((100 - 7* x) % 4 == 0){
int y = (100-7*x) / 4;
int z = 100 - x - y;
System.out.println(x + " " + y + " " + z);
}
}
}
}
}
29.计算日期到天数转换
描述
根据输入的日期,计算是这一年的第几天。
保证年份为4位数且日期合法。
进阶:时间复杂度:O(n)O(n) ,空间复杂度:O(1)O(1)
输入描述:
输入一行,每行空格分割,分别是年,月,日
输出描述:
输出是这一年的第几天
示例1
输入:
2012 12 31
复制
输出:
366
复制
示例2
输入:
1982 3 4
复制
输出:
63
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] dayofmonth = new int[] {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
while(sc.hasNext()){
int year = sc.nextInt();
int month = sc.nextInt();
int day = sc.nextInt();
int count = 0; //统计天数
for(int i = 0; i < month - 1; i++) //取前面的月份
count += dayofmonth[i];
count += day; //当月天数
if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) //闰年
if(month > 2) //大于2月的多加一天
count++;
System.out.println(count);
}
}
}
30.尼科彻斯定理
描述
验证尼科彻斯定理,即:任何一个整数m的立方都可以写成m个连续奇数之和。
例如:
1^3=1
2^3=3+5
3^3=7+9+11
4^3=13+15+17+19
输入一个正整数m(m≤100),将m的立方写成m个连续奇数之和的形式输出。
数据范围:1le mle 1001≤m≤100
进阶:时间复杂度:O(m)O(m) ,空间复杂度:O(1)O(1)
输入描述:
输入一个int整数
输出描述:
输出分解后的string
示例1
输入:
6
复制
输出:
31+33+35+37+39+41
题解: 等差数列公式:(其中a1表示第1项,an表示第n项,n表示项数,d表示公差,Sn表示前n项之和)
求末项:an=a1+(n-1)d(a1>an)
求首项a1=an-(n-1)d(a1>an)
求项数:n=[(an-a1)/d]+1
求公差:d=(an-a1)/(d-1)
求和:Sn=(a1+an)*n/2 或者Sn=na1+dn(n-2)/2
题目的意思是已知等差数列和 m的三次方 ,项数n为m,公差d为2,求首项a1 :
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNextInt()) {
int n = in.nextInt();
long sum = (long)n*n*n;
int a1 = (int)sum/n - (n - 1);
StringBuilder sb = new StringBuilder(Integer.toString(a1));
for(int i = 1; i < n; i++){
a1 = a1 + 2;
sb.append("+");
sb.append(a1);
}
System.out.println(sb);
}
}
}
31.整型数组合并
描述
题目标题:
将两个整型数组按照升序合并,并且过滤掉重复数组元素。
输出时相邻两数之间没有空格。
输入描述:
输入说明,按下列顺序输入:
1 输入第一个数组的个数
2 输入第一个数组的数值
3 输入第二个数组的个数
4 输入第二个数组的数值
输出描述:
输出合并之后的数组
示例1
输入:
3
1 2 5
4
-1 0 3 2
复制
输出:
-101235
public class Main {
public static void main(String[] args) throws ScriptException {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
Set<Long> set = new TreeSet<>();
//接收第一个整形数组大小
int size1 = sc.nextInt();
for (int i = 0; i < size1; i++) {
set.add(sc.nextLong()); //将该组的整数按数组大小循环添加进 set
}
//接收第一个整形数组大小
int size2 = sc.nextInt();
for (int i = 0; i < size2; i++) {
set.add(sc.nextLong());
}
//遍历输出
for (long n : set) {
System.out.print(n);
}
System.out.println();
}
}
}
32.字符串字符匹配
描述
判断短字符串S中的所有字符是否在长字符串T中全部出现。
请注意本题有多组样例输入。
数据范围:1le len(S),len(T)le2001≤len(S),len(T)≤200
进阶:时间复杂度:O(n)O(n) ,空间复杂度:O(n)O(n)
输入描述:
输入两个字符串。第一个为短字符串,第二个为长字符串。两个字符串均由小写字母组成。
输出描述:
如果短字符串的所有字符均在长字符串中出现过,则输出字符串"true"。否则输出字符串"false"。
示例1
输入:
bc
abc
复制
输出:
true
复制
说明:
其中abc含有bc,输出"true"
//用Set走捷径!把短字符串的字符加入到Set中,把长字符的字符从Set中剔除,如果最后Set为空,则满足条件。
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
String shortstr = in.nextLine();
String longstr = in.nextLine();
Set<Character> set = new HashSet<>();
for(int i=0;i<shortstr.length();++i){
set.add(shortstr.charAt(i));
}
for(int i=0;i<longstr.length();++i){
set.remove(longstr.charAt(i));
}
System.out.println(set.size()==0);
}
}
}
33.二维数组操作
34.统计大写字母个数
35.最长回文子串
描述
给定一个仅包含小写字母的字符串,求它的最长回文子串的长度。
所谓回文串,指左右对称的字符串。
所谓子串,指一个字符串删掉其部分前缀和后缀(也可以不删)的字符串
数据范围:字符串长度1le sle 3501≤s≤350
进阶:时间复杂度:O(n)O(n) ,空间复杂度:O(n)O(n)
输入描述:
输入一个仅包含小写字母的字符串
输出描述:
返回最长回文子串的长度
示例1
输入:
cdabbacc
复制
输出:
4
复制
说明:
abba为最长的回文子串
35.求最大连续bit数
36.密码强度等级
37.走方格的方案数
38.计票统计
39.表示数字
40.记负均正
Scanner sc = new Scanner(System.in);
int count1 = 0;// 正数个数
int count2 = 0;// 负数个数
int count3 = 0;// 其它
double average = 0;// 正数平均值
double sum = 0;
while (sc.hasNext()) {
int num = sc.nextInt();
if (num > 0) {
count1++;
sum+=num;
} else if (num < 0) {
count2++;
} else {
count3++;
}
System.in.close();// 本地IDE测试需要关闭流
}//输入循环结束花括号在这里
System.out.println(count2);
if (count1 == 0) {
System.out.println("0.0");
} else {
average = sum/(count1+count3);
System.out.printf("%.1fn",average);
}
41.自守数
public static void zsh(){
Scanner input = new Scanner(System.in);
while(input.hasNext()){
int n=input.nextInt();
int sum=0;
for (int i = 0; i <=n; i++) {
String str = String.valueOf(i * i);
String s1 = String.valueOf(i);
if(str.endsWith(s1)){
sum++;
}
}
System.out.println(sum);
}
}
42.等差数列
public static void dcsl(){
int input = new Scanner(System.in).nextInt();
int sum=0;
for (int i = 1; i <= input; i++) {
sum=sum+(3*i-1);
}
System.out.println(sum);
}
43.字符统计
44.记负均正||
描述
输入 n 个整型数,统计其中的负数个数并求所有非负数的平均值,结果保留一位小数,如果没有非负数,则平均值为0
本题有多组输入数据,输入到文件末尾。
数据范围:1 le n le 50000 1≤n≤50000 ,其中每个数都满足 |val| le 10^{6} ∣val∣≤10
6
输入描述:
输入任意个整数,每行输入一个。
输出描述:
输出负数个数以及所有非负数的平均值
示例1
输入:
-13
-4
-7
复制
输出:
3
0.0
复制
示例2
输入:
-12
1
2
复制
输出:
1
1.5
45.字符逆序
描述
将一个字符串str的内容颠倒过来,并输出。
数据范围:1 le len(str) le 100001≤len(str)≤10000
输入描述:
输入一个字符串,可以有空格
输出描述:
输出逆序的字符串
示例1
输入:
I am a student
复制
输出:
tneduts a ma I
复制
示例2
输入:
nowcoder
复制
输出:
redocwon
public class Main {
public static void main(String[] args) throws ScriptException {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
StringBuffer stringBuffer = new StringBuffer(s);
System.out.print(stringBuffer.reverse());
}
}
46.求最小公倍数
描述
正整数A和正整数B 的最小公倍数是指 能被A和B整除的最小的正整数值,设计一个算法,求输入A和B的最小公倍数。
数据范围:1 le a,b le 100000 1≤a,b≤100000
输入描述:
输入两个正整数A和B。
输出描述:
输出A和B的最小公倍数。
示例1
输入:
5 7
复制
输出:
35
复制
示例2
输入:
2 4
复制
输出:
4
public class Main {
public static void main(String[] args) throws ScriptException {
//解题思路:gcd求公约数,再用 最小公倍数 = a*b/最大公约数 公式求公倍数
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int a =sc.nextInt();
int b=sc.nextInt();
BigInteger bigInteger = BigInteger.valueOf(a);
BigInteger bigInteger1 = BigInteger.valueOf(b);
//求最大公约数
BigInteger gcd = bigInteger.gcd(bigInteger1);
//最小公倍数 = a*b/最大公约数
int gys = gcd.intValue();
int i = a * b / gys;
System.out.println(i);
}
}
}
三、中等
1.购物单
描述
王强决定把年终奖用于购物,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子:
主件 附件
电脑 打印机,扫描仪
书柜 图书
书桌 台灯,文具
工作椅 无
如果要买归类为附件的物品,必须先买该附件所属的主件,且每件物品只能购买一次。
每个主件可以有 0 个、 1 个或 2 个附件。附件不再有从属于自己的附件。
王强查到了每件物品的价格(都是 10 元的整数倍),而他只有 N 元的预算。除此之外,他给每件物品规定了一个重要度,用整数 1 ~ 5 表示。他希望在花费不超过 N 元的前提下,使自己的满意度达到最大。
满意度是指所购买的每件物品的价格与重要度的乘积的总和,假设设第ii件物品的价格为v[i]v[i],重要度
为w[i]w[i]请你帮助王强计算可获得的最大的满意度。
输入描述:
输入的第 1 行,为两个正整数N,m,用一个空格隔开:
(其中 N ( N<32000 )表示总钱数, m (m <60 )为可购买的物品的个数。)
从第 2 行到第 m+1 行,第 j 行给出了编号为 j-1 的物品的基本数据,每行有 3 个非负整数 v p q
(其中 v 表示该物品的价格( v<10000 ), p 表示该物品的重要度( 1 ~ 5 ), q 表示该物品是主件还是附件。如果 q=0 ,表示该物品为主件,如果 q>0 ,表示该物品为附件, q 是所属主件的编号)
输出描述:
输出一个正整数,为张强可以获得的最大的满意度。
示例1
输入:
1000 5
800 2 0
400 5 1
300 5 1
400 3 0
500 2 0
复制
输出:
2200
复制
示例2
输入:
50 5
20 3 5
20 3 5
10 3 0
10 2 0
10 1 0
复制
输出:
130
复制
说明:
由第1行可知总钱数N为50以及希望购买的物品个数m为5;
第2和第3行的q为5,说明它们都是编号为5的物品的附件;
第46行的q都为0,说明它们都是主件,它们的编号依次为35;
所以物品的价格与重要度乘积的总和的最大值为101+203+20*3=130
2.坐标移动
描述
开发一个坐标计算工具, A表示向左移动,D表示向右移动,W表示向上移动,S表示向下移动。从(0,0)点开始移动,从输入字符串里面读取一些坐标,并将最终输入结果输出到输出文件里面。
输入:
合法坐标为A(或者D或者W或者S) + 数字(两位以内)
坐标之间以;分隔。
非法坐标点需要进行丢弃。如AA10; A1A; % ; YAD; 等。
下面是一个简单的例子 如:
A10;S20;W10;D30;X;A1A;B10A11;;A10;
处理过程:
起点(0,0)
-
A10 = (-10,0)
-
S20 = (-10,-20)
-
W10 = (-10,-10)
-
D30 = (20,-10)
-
x = 无效
-
A1A = 无效
-
B10A11 = 无效
-
一个空 不影响
-
A10 = (10,-10)
结果 (10, -10)
数据范围:每组输入的字符串长度满足 1le n le 10000 1≤n≤10000 ,坐标保证满足 -2^{31} le x,y le 2^{31}-1 −2
31
≤x,y≤2
31
−1 ,且数字部分仅含正数
输入描述:
一行字符串
输出描述:
最终坐标,以逗号分隔
示例1
输入:
A10;S20;W10;D30;X;A1A;B10A11;;A10;
输出:
10,-10
示例2
输入:
ABC;AKL;DA1;
输出:
0,0
import java.io.IOException;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
int x = 0, y = 0;
String[] strs = in.next().split(";");
for(String s : strs) {
if( s == null || s.trim().length() == 0) {
continue;
}
String di = s.substring(0,1);
if(!("A".equals(di) || "D".equals(di) || "W".equals(di) || "S".equals(di)) ){
continue;
}
int mv = 0;
try{
mv = Integer.valueOf(s.substring(1));
if(mv>=100 || mv <=0){
continue;
}
}catch(Exception e){
continue;
}
if("A".equals(di)){
x -= mv;
} else if("D".equals(di)){
x += mv;
} else if("W".equals(di)){
y += mv;
} else if("S".equals(di)){
y -= mv;
}
}
System.out.println(x + "," + y);
}
}
}
3.密码验证合格程序
描述
密码要求:
1.长度超过8位
2.包括大小写字母.数字.其它符号,以上四种至少三种
3.不能有长度大于2的包含公共元素的子串重复 (注:其他符号不含空格或换行)
数据范围:输入的字符串长度满足 1 le n le 100 1≤n≤100
输入描述:
一组字符串。
输出描述:
如果符合要求输出:OK,否则输出NG
示例1
输入:
021Abc9000
021Abc9Abc1
021ABC9000
021$bc9000
输出:
OK
NG
NG
OK
import java.io.IOException;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextLine()) {
String password = scanner.nextLine();
char[] chars = password.toCharArray();
if (password.length() > 8) {
int a = 0, b = 0, e = 0, d = 0;
boolean err = true;
for (char c : chars) {
// 数字
if (c >= '0' && c <= '9') {
a = 1;
} else if (c >= 'a' && c <= 'z') {
b = 1;
} else if (c >= 'A' && c <= 'Z') {
d = 1;
} else if (c == ' ' || c == 'n') {
//存在空格或换行
err = false;
break;
} else {
e = 1;
}
}
if (err) {
if ((a + b + d + e) >= 3) {
if (reStr(password)) {
System.out.println("OK");
} else {
// 重复字符串
System.out.println("NG");
}
} else {
// 字符种类小于三种
System.out.println("NG");
}
} else {
//存在空格
System.out.println("NG");
}
} else {
// 长度小于等于8
System.out.println("NG");
}
}
}
private static boolean reStr(String s) {
for (int i = 3; i < s.length(); i++) {
if (s.substring(i).contains(s.substring(i - 3, i))) {
return false;
}
}
return true;
}
}
4.合唱队
5.字符串排序
描述
编写一个程序,将输入字符串中的字符按如下规则排序。
规则 1 :英文字母从 A 到 Z 排列,不区分大小写。
如,输入: Type 输出: epTy
规则 2 :同一个英文字母的大小写同时存在时,按照输入顺序排列。
如,输入: BabA 输出: aABb
规则 3 :非英文字母的其它字符保持原来的位置。
如,输入: By?e 输出: Be?y
数据范围:输入的字符串长度满足 1 le n le 1000 1≤n≤1000
输入描述:
输入字符串
输出描述:
输出字符串
示例1
输入:
A Famous Saying: Much Ado About Nothing (2012/8).
复制
输出:
A aaAAbc dFgghh: iimM nNn oooos Sttuuuy (2012/8).
import java.util.*;
public class Main {
public static String sort(String str) {
// 先将英文字母收集起来
List<Character> letters = new ArrayList<>();
for (char ch : str.toCharArray()) {
if (Character.isLetter(ch)) {
letters.add(ch);
}
}
// 将英文字母先排序好
letters.sort(new Comparator<Character>() {
public int compare(Character o1, Character o2) {
return Character.toLowerCase(o1) - Character.toLowerCase(o2);
}
});
// 若是非英文字母则直接添加 Character.isLetter判断是否为字母
StringBuilder result = new StringBuilder();
for (int i = 0, j = 0; i < str.length(); i++) {
if (Character.isLetter(str.charAt(i))) {
result.append(letters.get(j++));
}
else {
result.append(str.charAt(i));
}
}
return result.toString();
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNextLine()) {
String str = in.nextLine();
String res = sort(str);
System.out.println(res);
}
}
}
6.查找兄弟单词
描述
定义一个单词的“兄弟单词”为:交换该单词字母顺序(注:可以交换任意次),而不添加、删除、修改原有的字母就能生成的单词。
兄弟单词要求和原来的单词不同。例如: ab 和 ba 是兄弟单词。 ab 和 ab 则不是兄弟单词。
现在给定你 n 个单词,另外再给你一个单词 x ,让你寻找 x 的兄弟单词里,按字典序排列后的第 k 个单词是什么?
注意:字典中可能有重复单词。
数据范围:1 le n le 1000 1≤n≤1000 ,输入的字符串长度满足 1 le len(str) le 10 1≤len(str)≤10 , 1 le k < n 1≤k<n
输入描述:
输入只有一行。 先输入字典中单词的个数n,再输入n个单词作为字典单词。 然后输入一个单词x 最后后输入一个整数k
输出描述:
第一行输出查找到x的兄弟单词的个数m 第二行输出查找到的按照字典顺序排序后的第k个兄弟单词,没有符合第k个的话则不用输出。
示例1
输入:
3 abc bca cab abc 1
复制
输出:
2
bca
复制
示例2
输入:
6 cab ad abcd cba abc bca abc 1
复制
输出:
3
bca
复制
说明:
abc的兄弟单词有cab cba bca,所以输出3
经字典序排列后,变为bca cab cba,所以第1个字典序兄弟单词为bca
7.字符串加密解密
描述
对输入的字符串进行加解密,并输出。
加密方法为:
当内容是英文字母时则用该英文字母的后一个字母替换,同时字母变换大小写,如字母a时则替换为B;字母Z时则替换为a;
当内容是数字时则把该数字加1,如0替换1,1替换2,9替换0;
其他字符不做变化。
解密方法为加密的逆过程。
数据范围:输入的两个字符串长度满足 1 le n le 1000 1≤n≤1000 ,保证输入的字符串都是只由大小写字母或者数字组成
输入描述:
第一行输入一串要加密的密码
第二行输入一串加过密的密码
输出描述:
第一行输出加密后的字符
第二行输出解密后的字符
示例1
输入:
abcdefg
BCDEFGH
复制
输出:
BCDEFGH
abcdefg
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Scanner;
import java.util.*;
public class Main{
public static void main(String []args) throws Exception{
Scanner in = new Scanner(System.in);
String xx="abcdefghijklmnopqrstuvwxyz";
String dx="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
//要加密的密码
String str = in.nextLine();
//要解密的密码
String str1 = in.nextLine();
add ( xx, dx, str);
sub ( xx, dx, str1);
}
public static void add (String xx,String dx,String str){
char[] chars = str.toCharArray();
for (int i = 0; i < chars.length; i++) {
if('0'<=chars[i] && chars[i]<='9'){
if(chars[i]=='9'){
str= str.substring(0, i) + "0" + str.substring(i + 1);//替换
}else{
int rep = Integer.valueOf(String.valueOf(chars[i])) + 1;
str= str.substring(0, i) + rep + str.substring(i + 1);//替换
}
}
if('a'<=chars[i] && chars[i]<='z'){
if(chars[i]=='z'){
str= str.substring(0, i) + "A" + str.substring(i + 1);//替换
}else{
int index = xx.indexOf(chars[i]);
char c = xx.charAt(index + 1);
String s = String.valueOf(c).toUpperCase();//转大写
str= str.substring(0, i) + s + str.substring(i + 1);//替换
}
} else if('A'<=chars[i] && chars[i]<='Z'){
if(chars[i]=='Z'){
str= str.substring(0, i) + "a" + str.substring(i + 1);//替换
}else{
int index = dx.indexOf(chars[i]);
char c = dx.charAt(index + 1);
String s = String.valueOf(c).toLowerCase();//转小写
str= str.substring(0, i) + s + str.substring(i + 1);//替换
}
}
}
System.out.println(str);
}
public static void sub (String xx,String dx,String str1){
String str=str1;
//System.out.println("开始解密字符换:"+str);
char[] chars = str.toCharArray();
for (int i = 0; i < chars.length; i++) {
if('0'<=chars[i] && chars[i]<='9'){
if(chars[i]=='0'){
str= str.substring(0, i) + "9" + str.substring(i + 1);//替换
}else{
//System.out.print("第"+i+"个字符串是数字");
int rep = Integer.valueOf(String.valueOf(chars[i])) - 1;
str= str.substring(0, i) + rep + str.substring(i + 1);//替换
//System.out.println("转换后变成"+str);
}
} else if('a'<=chars[i] && chars[i]<='z'){
if(chars[i]=='a'){
//System.out.print("第"+i+"个字符串是小写字母z");
str= str.substring(0, i) + "Z" + str.substring(i + 1);//替换
}else{
//System.out.print("第"+i+"个字符串是小写字母"+chars[i]);
int index = xx.indexOf(chars[i]);
char c = xx.charAt(index - 1);
String s = String.valueOf(c).toUpperCase();//转大写
//System.out.println("转成大写"+s);
str= str.substring(0, i) + s + str.substring(i + 1);//替换
//System.out.println("转换后变成"+str);
}
}else if('A'<=chars[i] && chars[i]<='Z'){
if(chars[i]=='A'){
//System.out.print("第"+i+"个字符串是大写字母A");
str= str.substring(0, i) + "z" + str.substring(i + 1);//替换
}else{
//System.out.print("第"+i+"个字符串是大写字母"+chars[i]);
int index = dx.indexOf(chars[i]);
char c = dx.charAt(index - 1);
String s = String.valueOf(c).toLowerCase();//转小写
//System.out.println("转成小写:"+s);
str= str.substring(0, i) + s + str.substring(i + 1);//替换
//System.out.println("转换后变成"+str);
}
}
}
System.out.println(str);
}
}
8.密码截取
描述
Catcher是MCA国的情报员,他工作时发现敌国会用一些对称的密码进行通信,比如像这些ABBA,ABA,A,123321,但是他们有时会在开始或结束时加入一些无关的字符以防止别国破解。比如进行下列变化 ABBA->12ABBA,ABA->ABAKK,123321->51233214 。因为截获的串太长了,而且存在多种可能的情况(abaaab可看作是aba,或baaab的加密形式),Cathcer的工作量实在是太大了,他只能向电脑高手求助,你能帮Catcher找出最长的有效密码串吗?
数据范围:字符串长度满足 1 le n le 2500 1≤n≤2500
输入描述:
输入一个字符串(字符串的长度不超过2500)
输出描述:
返回有效密码串的最大长度
示例1
输入:
ABBA
复制
输出:
4
复制
示例2
输入:
ABBBA
复制
输出:
5
复制
示例3
输入:
12HHHHA
复制
输出:
4
public class Main {
public static void main(String[] args) throws ScriptException {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
int res = 0;
for(int i = 0; i < s.length(); i++) {
// ABA型
int len1 = longest(s, i, i);
// ABBA型
int len2 = longest(s, i, i + 1);
res = Math.max(res, len1 > len2 ? len1 : len2);
}
System.out.println(res);
}
private static int longest(String s, int l, int r) {
while(l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) {
l--;
r++;
}
return r - l - 1;
}
9.整数与IP地址之间的转换
10.字符串加密
描述
有一种技巧可以对数据进行加密,它使用一个单词作为它的密匙。下面是它的工作原理:首先,选择一个单词作为密匙,如TRAILBLAZERS。如果单词中包含有重复的字母,只保留第1个,将所得结果作为新字母表开头,并将新建立的字母表中未出现的字母按照正常字母表顺序加入新字母表。如下所示:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
T R A I L B Z E S C D F G H J K M N O P Q U V W X Y (实际需建立小写字母的字母表,此字母表仅为方便演示)
上面其他用字母表中剩余的字母填充完整。在对信息进行加密时,信息中的每个字母被固定于顶上那行,并用下面那行的对应字母一一取代原文的字母(字母字符的大小写状态应该保留)。因此,使用这个密匙, Attack AT DAWN (黎明时攻击)就会被加密为Tpptad TP ITVH。
请实现下述接口,通过指定的密匙和明文得到密文。
数据范围:1 le n le 100 1≤n≤100 ,保证输入的字符串中仅包含小写字母
输入描述:
先输入key和要加密的字符串
输出描述:
返回加密后的字符串
示例1
输入:
nihao
ni
复制
输出:
le
11.求小球落地5次后经历的路程和第五次反弹的高度
描述
假设一个球从任意高度自由落下,每次落地后反跳回原高度的一半; 再落下, 求它在第5次落地时,共经历多少米?第5次反弹多高?
数据范围:输入的小球初始高度满足 1 le n le 1000 1≤n≤1000 ,且保证是一个整数
输入描述:
输入起始高度,int型
输出描述:
分别输出第5次落地时,共经过多少米以及第5次反弹多高。
注意:你可以认为你输出保留六位或以上小数的结果可以通过此题。
示例1
输入:
1
输出:
2.875
0.03125
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
double aDouble = n;
double sum1 = 0;//下路的高度
double sum = 0;//弹起来的高度
for (int i = 1; i <= 5; i++) {
sum1+=aDouble;
aDouble=aDouble/2; //弹起来的高度
sum+=aDouble;
}
System.out.println(sum1 + sum - aDouble);
System.out.println(aDouble);
}
}
12.称砝码
描述
现有n种砝码,重量互不相等,分别为 m1,m2,m3…mn ;
每种砝码对应的数量为 x1,x2,x3…xn 。现在要用这些砝码去称物体的重量(放在同一侧),问能称出多少种不同的重量。
注:
称重重量包括 0
数据范围:每组输入数据满足 1 le n le 10 1≤n≤10 , 1 le m_i le 2000 1≤m
i
≤2000 , 1 le x_i le 10 1≤x
i
≤10
输入描述:
对于每组测试数据:
第一行:n — 砝码的种数(范围[1,10])
第二行:m1 m2 m3 … mn — 每种砝码的重量(范围[1,2000])
第三行:x1 x2 x3 … xn — 每种砝码对应的数量(范围[1,10])
输出描述:
利用给定的砝码可以称出的不同的重量数
示例1
输入:
2
1 2
2 1
复制
输出:
5
复制
说明:
可以表示出0,1,2,3,4五种重量。
13.迷宫问题
描述
定义一个二维数组 N*M ,如 5 × 5 数组下所示:
int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的路线。入口点为[0,0],既第一格是可以走的路。
数据范围: 2 le n,m le 10 2≤n,m≤10 , 输入的内容只包含 0 le val le 1 ≤val≤1
输入描述:
输入两个整数,分别表示二维数组的行数,列数。再输入相应的数组,其中的1表示墙壁,0表示可以走的路。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。
输出描述:
左上角到右下角的最短路径,格式如样例所示。
示例1
输入:
5 5
0 1 0 0 0
0 1 1 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
复制
输出:
(0,0)
(1,0)
(2,0)
(2,1)
(2,2)
(2,3)
(2,4)
(3,4)
(4,4)
复制
示例2
输入:
5 5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 1
0 1 1 1 0
0 0 0 0 0
复制
输出:
(0,0)
(1,0)
(2,0)
(3,0)
(4,0)
(4,1)
(4,2)
(4,3)
(4,4)
复制
说明:
注意:不能斜着走!!
14.名字的漂亮度
描述
给出一个字符串,该字符串仅由小写字母组成,定义这个字符串的“漂亮度”是其所有字母“漂亮度”的总和。
每个字母都有一个“漂亮度”,范围在1到26之间。没有任何两个不同字母拥有相同的“漂亮度”。字母忽略大小写。
给出多个字符串,计算每个字符串最大可能的“漂亮度”。
本题含有多组数据。
数据范围:输入的名字长度满足 1 le n le 10000 1≤n≤10000
输入描述:
第一行一个整数N,接下来N行每行一个字符串
输出描述:
每个字符串可能的最大漂亮程度
示例1
输入:
2
zhangsan
lisi
复制
输出:
192
101
复制
说明:
对于样例lisi,让i的漂亮度为26,l的漂亮度为25,s的漂亮度为24,lisi的漂亮度为25+26+24+26=101.
public class Main {
public static void main(String[] args) throws ScriptException {
//zhangsan ==》 aa nn z h g s ==> a(26) + a(26) + n(25) + n(25) + z(24) + h(23) + g(22) + s(21) = 192
Scanner in = new Scanner(System.in);
int n = in.nextInt();
in.nextLine();//跳到第二行
for(int i=0;i<n;i++){
System.out.println(getScore(in.nextLine()));
}
}
public static int getScore(String name){
int score = 0;
char[] cha = name.toCharArray();
int[] count = new int[26];
for(int i=0;i<cha.length;i++){
count[cha[i] - 'a']++;//统计每个字母出现的次数,忽略大小写
}
Arrays.sort(count);//升序排列
for(int i=1;i<=26;i++){//计算漂亮度
score += i * count[i-1];
}
return score;
}
}
15.从单向链表中删除指定值的节点
16.四则运算
描述
输入一个表达式(用字符串表示),求这个表达式的值。
保证字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。且表达式一定合法。
数据范围:表达式计算结果和过程中满足 |val| le 1000 ∣val∣≤1000 ,字符串长度满足 1 le n le 1000 1≤n≤1000
输入描述:
输入一个算术表达式
输出描述:
得到计算结果
示例1
输入:
3+2*{1+2*[-4/(8-6)+7]}
复制
输出:
25
public class Main {
public static void main(String[] args) throws ScriptException {
Scanner scan = new Scanner(System.in);
String input = scan.nextLine();
input = input.replace("[","(");
input = input.replace("{","(");
input = input.replace("}",")");
input = input.replace("]",")");
//js的
ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("nashorn");
System.out.println(scriptEngine.eval(input));
}
}
17.计算字符串的编辑距离
描述
Levenshtein 距离,又称编辑距离,指的是两个字符串之间,由一个转换成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。编辑距离的算法是首先由俄国科学家 Levenshtein 提出的,故又叫 Levenshtein Distance 。
例如:
字符串A: abcdefg
字符串B: abcdef
通过增加或是删掉字符 ”g” 的方式达到目的。这两种方案都需要一次操作。把这个操作所需要的次数定义为两个字符串的距离。
要求:
给定任意两个字符串,写出一个算法计算它们的编辑距离。
数据范围:给定的字符串长度满足 1 le len(str) le 1000 1≤len(str)≤1000
输入描述:
每组用例一共2行,为输入的两个字符串
输出描述:
每组用例输出一行,代表字符串的距离
示例1
输入:
abcdefg
abcdef
复制
输出:
1
18.挑7
描述
输出 1到n之间 的与 7 有关数字的个数。
一个数与7有关是指这个数是 7 的倍数,或者是包含 7 的数字(如 17 ,27 ,37 … 70 ,71 ,72 ,73…)
数据范围: 1 le n le 30000 1≤n≤30000
输入描述:
一个正整数 n 。( n 不大于 30000 )
输出描述:
一个整数,表示1到n之间的与7有关的数字个数。
示例1
输入:
20
复制
输出:
3
复制
说明:
输入20,1到20之间有关的数字包括7,14,17共3个。
import java.util.*;
public class Main {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
int n = sc.nextInt();
int sum=0;
for(int i = 1;i<=n;i++){
if(i%7==0){
sum++;
}else{
String s = String.valueOf(i);
if(s.contains("7")){
sum++;
}
}
}
System.out.println(sum);
}
}
}
19.高精度整数加法
描述
输入两个用字符串 str 表示的整数,求它们所表示的数之和。
数据范围: 1 le len(str) le 10000 1≤len(str)≤10000
输入描述:
输入两个字符串。保证字符串只含有’0’~'9’字符
输出描述:
输出求和后的结果
示例1
输入:
9876543210
1234567890
复制
输出:
11111111100
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while (scan.hasNext()) {
String s1 = scan.next();
String s2 = scan.next(); //输入两个数
BigInteger a = new BigInteger(s1); //将字符串转成大整数
BigInteger b = new BigInteger(s2);
System.out.println(a.add(b)); //大整数相加
}
}
}
20.找出字符串中第一个只出现一次的字符
描述
找出字符串中第一个只出现一次的字符
数据范围:输入的字符串长度满足 1 le n le 1000 1≤n≤1000
输入描述:
输入一个非空字符串
输出描述:
输出第一个只出现一次的字符,如果不存在输出-1
示例1
输入:
asdfasdfo
复制
输出:
o
public class Main {
public static void main(String[] args) throws ScriptException {
Scanner sc = new Scanner(System.in);
Map<Character, Integer> map = new LinkedHashMap<>();
String line = sc.nextLine();
for (int i = 0; i < line.length(); i++) {
char c = line.charAt(i);
map.put(c, map.getOrDefault(c, 0) + 1);
}
boolean flag = false;
for (Map.Entry<Character, Integer> entry : map.entrySet()) {
if (entry.getValue() == 1) {
System.out.println(entry.getKey());
flag = true;
break;
}
}
if (!flag) {
System.out.println(-1);
}
}
}
21.DNA序列
22.MP3光标位置
23.查找两个字符串a,b中最长的公共子串
24.配置文件恢复
25.24点游戏算法
26.矩阵乘法
27.矩阵乘法计算量估算
28.字符串通配符
29.参数解析
描述
在命令行输入如下命令:
xcopy /s c: d:e,
各个参数如下:
参数1:命令字xcopy
参数2:字符串/s
参数3:字符串c:
参数4: 字符串d:e
请编写一个参数解析程序,实现将命令行各个参数解析出来。
解析规则:
1.参数分隔符为空格
2.对于用""包含起来的参数,如果中间有空格,不能解析为多个参数。比如在命令行输入xcopy /s “C:program files” "d:“时,参数仍然是4个,第3个参数应该是字符串C:program files,而不是C:program,注意输出参数时,需要将”"去掉,引号不存在嵌套情况。
3.参数不定长
4.输入由用例保证,不会出现不符合要求的输入
数据范围:字符串长度:1le sle 10001≤s≤1000
进阶:时间复杂度:O(n)O(n) ,空间复杂度:O(n)O(n)
输入描述:
输入一行字符串,可以有空格
输出描述:
输出参数个数,分解后的参数,每个参数都独占一行
示例1
输入:
xcopy /s c: d:e
复制
输出:
4
xcopy
/s
c:
d:e
30.公共子串计算
描述
给定两个只包含小写字母的字符串,计算两个字符串的最大公共子串的长度。
注:子串的定义指一个字符串删掉其部分前缀和后缀(也可以不删)后形成的字符串。
数据范围:字符串长度:1le sle 1501≤s≤150
进阶:时间复杂度:O(n^3)O(n
3
) ,空间复杂度:O(n)O(n)
输入描述:
输入两个只包含小写字母的字符串
输出描述:
输出一个整数,代表最大公共子串的长度
示例1
输入:
asdfas
werasdfaswer
复制
输出:
6
31.火车进站
描述
给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号,火车站只有一个方向进出,同时停靠在火车站的列车中,只有后进站的出站了,先进站的才能出站。
要求输出所有火车出站的方案,以字典序排序输出。
数据范围:1le nle 101≤n≤10
进阶:时间复杂度:O(n!)O(n!) ,空间复杂度:O(n)O(n)
输入描述:
第一行输入一个正整数N(0 < N <= 10),第二行包括N个正整数,范围为1到10。
输出描述:
输出以字典序从小到大排序的火车出站序列号,每个编号以空格隔开,每个输出序列换行,具体见sample。
示例1
输入:
3
1 2 3
复制
输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 2 1
复制
说明:
第一种方案:1进、1出、2进、2出、3进、3出
第二种方案:1进、1出、2进、3进、3出、2出
第三种方案:1进、2进、2出、1出、3进、3出
第四种方案:1进、2进、2出、3进、3出、1出
第五种方案:1进、2进、3进、3出、2出、1出
请注意,[3,1,2]这个序列是不可能实现的。
32.将真分数分解为埃及分数
描述
分子为1的分数称为埃及分数。现输入一个真分数(分子比分母小的分数,叫做真分数),请将该分数分解为埃及分数。如:8/11 = 1/2+1/5+1/55+1/110。
注:真分数指分子小于分母的分数,分子和分母有可能gcd不为1!
如有多个解,请输出任意一个。
输入描述:
输入一个真分数,String型
输出描述:
输出分解后的string
示例1
输入:
8/11
2/4
复制
输出:
1/2+1/5+1/55+1/110
1/3+1/6
复制
说明:
第二个样例直接输出1/2也是可以的
33.合法IP
34.字符串中找出连续最长的数字串
35.Redraiment的走法
描述
Redraiment是走梅花桩的高手。Redraiment可以选择任意一个起点,从前到后,但只能从低处往高处的桩子走。他希望走的步数最多,你能替Redraiment研究他最多走的步数吗?
数据范围:每组数据长度满足 1 le n le 200 1≤n≤200 , 数据大小满足 1 le val le 350 1≤val≤350
输入描述:
数据共2行,第1行先输入数组的个数,第2行再输入梅花桩的高度
输出描述:
输出一个结果
示例1
输入:
6
2 5 1 5 4 5
复制
输出:
3
复制
说明:
6个点的高度各为 2 5 1 5 4 5
如从第1格开始走,最多为3步, 2 4 5 ,下标分别是 1 5 6
从第2格开始走,最多只有1步,5
而从第3格开始走最多有3步,1 4 5, 下标分别是 3 5 6
从第5格开始走最多有2步,4 5, 下标分别是 5 6
所以这个结果是3。
35.求解立方根
描述
计算一个浮点数的立方根,不使用库函数。
保留一位小数。
数据范围:|val| le 20 ∣val∣≤20
输入描述:
待求解参数,为double类型(一个实数)
输出描述:
输出参数的立方根。保留一位小数。
示例1
输入:
19.9
复制
输出:
2.7
复制
示例2
输入:
2.7
复制
输出:
1.4
四、较难
1.明明的随机数
public static void mingming(){
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
TreeSet treeSet = new TreeSet();
int num = sc.nextInt();
for (int i = 0; i < num; i++) {
treeSet.add(sc.nextInt());
}
Iterator iterator = treeSet.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
2.识别有效ip地址和掩码进行分类统计
描述
请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。
所有的IP地址划分为 A,B,C,D,E五类
A类地址从1.0.0.0到126.255.255.255;
B类地址从128.0.0.0到191.255.255.255;
C类地址从192.0.0.0到223.255.255.255;
D类地址从224.0.0.0到239.255.255.255;
E类地址从240.0.0.0到255.255.255.255
私网IP范围是:
从10.0.0.0到10.255.255.255
从172.16.0.0到172.31.255.255
从192.168.0.0到192.168.255.255
子网掩码为二进制下前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码)
(注意二进制下全是1或者全是0均为非法子网掩码)
注意:
- 类似于【0...】和【127...】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略
- 私有IP地址和A,B,C,D,E类地址是不冲突的
输入描述:
多行字符串。每行一个IP地址和掩码,用~隔开。
请参考帖子https://www.nowcoder.com/discuss/276处理循环输入的问题。
输出描述:
统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。
示例1
输入:
10.70.44.68~255.254.255.0
1.0.0.1~255.0.0.0
192.168.0.2~255.255.255.0
19…0.~255.255.255.0
复制
输出:
1 0 1 0 0 2 1
复制
说明:
10.70.44.68255.254.255.0的子网掩码非法,19…0.255.255.255.0的IP地址非法,所以错误IP地址或错误掩码的计数为2;
1.0.0.1~255.0.0.0是无误的A类地址;
192.168.0.2~255.255.255.0是无误的C类地址且是私有IP;
所以最终的结果为1 0 1 0 0 2 1
示例2
输入:
0.201.56.50~255.255.111.255
127.201.56.50~255.255.111.255
复制
输出:
0 0 0 0 0 0 0
复制
说明:
类似于【0...】和【127...】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略
3.简单错误记录
4.数据分类处理
5.字符串合并处理
描述
按照指定规则对输入的字符串进行处理。
详细描述:
第一步:将输入的两个字符串str1和str2进行前后合并。如给定字符串 “dec” 和字符串 “fab” , 合并后生成的字符串为 “decfab”
第二步:对合并后的字符串进行排序,要求为:下标为奇数的字符和下标为偶数的字符分别从小到大排序。这里的下标的意思是字符在字符串中的位置。注意排序后在新串中仍需要保持原来的奇偶性。例如刚刚得到的字符串“decfab”,分别对下标为偶数的字符’d’、‘c’、‘a’和下标为奇数的字符’e’、‘f’、'b’进行排序(生成 ‘a’、‘c’、‘d’ 和 ‘b’ 、‘e’ 、‘f’),再依次分别放回原串中的偶数位和奇数位,新字符串变为“abcedf”
第三步:对排序后的字符串中的’0’‘9’、‘A’‘F’和’a’~'f’字符,需要进行转换操作。
转换规则如下:
对以上需要进行转换的字符所代表的十六进制用二进制表示并倒序,然后再转换成对应的十六进制大写字符(注:字符 a~f 的十六进制对应十进制的10~15,大写同理)。
如字符 ‘4’,其二进制为 0100 ,则翻转后为 0010 ,也就是 2 。转换后的字符为 ‘2’。
如字符 ‘7’,其二进制为 0111 ,则翻转后为 1110 ,对应的十进制是14,转换为十六进制的大写字母为 ‘E’。
如字符 ‘C’,代表的十进制是 12 ,其二进制为 1100 ,则翻转后为 0011,也就是3。转换后的字符是 ‘3’。
根据这个转换规则,由第二步生成的字符串 “abcedf” 转换后会生成字符串 “5D37BF”。
数据范围:输入的字符串长度满足 1 le n le 100 1≤n≤100
输入描述:
样例输入两个字符串,用空格隔开。
输出描述:
输出转化后的结果。
示例1
输入:
dec fab
复制
输出:
5D37BF
复制
示例2
输入:
ab CD
复制
输出:
3B5D
复制
说明:
合并后为abCD,按奇数位和偶数位排序后是CDab(请注意要按ascii码进行排序,所以C在a前面,D在b前面),转换后为3B5D
示例3
输入:
123 15
复制
输出:
88C4A
6.判断两个IP是否属于同一子网
7.学英语
8.成绩排序
9.整数与IP地址之间的转换
10.扑克牌大小
11.24点运算
12.数组分组
13.人民币转换
五、困难
1.素数伴侣
2.sudoku
3.自动售货系统
最后
以上就是精明时光为你收集整理的牛客网华为机考一、入门二、简单三、中等四、较难五、困难的全部内容,希望文章能够帮你解决牛客网华为机考一、入门二、简单三、中等四、较难五、困难所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复