华为机试练习代码
Posted biyangqiang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了华为机试练习代码相关的知识,希望对你有一定的参考价值。
长度为n的数组乱序存放着0至n-1. 现在只能进行0与其他数的交换.将数组中的元素按对应位置放置使得a[i]=i
import java.util.*; public class Main { public static void main(String[] args){ Scanner sc = new Scanner(System.in); // while(sc.hasNext()){ int arr [] ={5,3,4,2,0,1}; sort(arr); // } sc.close(); } public static void sort(int[] array) { int len = array.length; if(len <= 1){ return; } for(int i = len - 1; i > 0; --i){ //从最后一位开始,将最大的数放到最大位置上,然后依次找次大的放 if(array[i] == i) continue; //已经相等,则不交换,避免不必要的重复交换 swap_with_zero(array, array[i]); //现将0和最后一位交换,以便将第n最大值换到第n大位置上 //print(array); int curMax = array[i]; for(int j = i; j >= 0; --j){ //找出第n大的数 if(array[j] > curMax){ curMax = array[j]; } } swap_with_zero(array, curMax); //将第n大的数和0互换,从而放到第n大的位置上 print(array); } } public static void print(int[] arr){ for(int i=0;i<arr.length;i++){ System.out.print(" " + arr[i] + " "); } System.out.println(); for(int i=0;i<arr.length;i++){ System.out.print("[" + i + "]" + " "); } System.out.println(); System.out.println(); } public static void swap_with_zero(int[] array, int number){ int len = array.length; int zIndex = -1; int nIndex = -1; for(int i = 0; i < len; ++i){ if(array[i] == 0){ zIndex = i; } if(array[i] == number){ nIndex = i; } } int temp = array[zIndex]; array[zIndex] = array[nIndex]; array[nIndex] = temp; } }
题目描述
输入描述:
输入两个字符串
输出描述:
返回重复出现的字符
输入
abcdefghijklmnop abcsafjklmnopqrstuvw
输出
jklmnop
PS:之前提交错误 是 因为题目中有个 以最少的字符串为准
import java.util.*; public class Main{ public static void main(String args[]){ Scanner sc=new Scanner(System.in); while(sc.hasNext()){ ArrayList<String> list = new ArrayList<String>(); String str1 = sc.nextLine(); String str2 = sc.nextLine(); String content =null; String str=null; if(str1.length()<str2.length()){ content = str2; str = str1; }else{ content = str1; str = str2; } for(int i=str.length();i>0;i--){ for(int j = 0;j<str.length()-i+1;j++){ String substring = str.substring(j, j+(i)); if(content.contains(substring)){ list.add(substring); //System.out.println(substring); break; } } //break; } System.out.println(list.get(0)); } } }
题目描述
题目描述
把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。
输入
每个用例包含二个整数M和N。0<=m<=10,1<=n<=10。
样例输入
7 3
样例输出
8
/**
* 计算放苹果方法数目
* 输入值非法时返回-1
* 1 <= m,n <= 10
* @param m 苹果数目
* @param n 盘子数目数
* @return 放置方法总数
*
*/
public static int count(int m, int n)
输入描述:
输入两个int整数
输出描述:
输出结果,int型
输入
7 3
输出
8
PS:完全不会
import java.util.*;
/* 解题分析: 设f(m,n) 为m个苹果,n个盘子的放法数目,则先对n作讨论, 当n>m:必定有n-m个盘子永远空着,去掉它们对摆放苹果方法数目不产生影响。即if(n>m) f(m,n) = f(m,m) 当n<=m:不同的放法可以分成两类: 1、有至少一个盘子空着,即相当于f(m,n) = f(m,n-1); 2、所有盘子都有苹果,相当于可以从每个盘子中拿掉一个苹果,不影响不同放法的数目,即f(m,n) = f(m-n,n). 而总的放苹果的放法数目等于两者的和,即 f(m,n) =f(m,n-1)+f(m-n,n) 递归出口条件说明: 当n=1时,所有苹果都必须放在一个盘子里,所以返回1; 当没有苹果可放时,定义为1种放法; 递归的两条路,第一条n会逐渐减少,终会到达出口n==1; 第二条m会逐渐减少,因为n>m时,我们会return f(m,m) 所以终会到达出口m==0. */
public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); while(sc.hasNext()){ int m = sc.nextInt(); int n = sc.nextInt(); if(m<1 || n>10){ System.out.println(-1); }else{ System.out.println(shareCount(m,n)); } } } public static int shareCount(int m, int n){ if(m<0){ return 0; } if(m==1 || n==1){ return 1; } return shareCount(m, n-1)+shareCount(m-n,n); } }
题目描述
1
1 1 1
1 2 3 2 1
1 3 6 7 6 3 1
1 4 10 16 19 16 10 4 1
以上三角形的数阵,第一行只有一个数1,以下每行的每个数,是恰好是它上面的数,左上角数到右上角的数,3个数之和(如果不存在某个数,认为该数就是0)。
求第n行第一个偶数出现的位置。如果没有偶数,则输出-1。例如输入3,则输出2,输入4则输出3。
输入n(n <= 1000000000)
输入描述:
输入一个int整数
输出描述:
输出返回的int值
输入
4
输出
3
PS:心得:不用太固执去看一个东西,要有发散思维 //完全是个找规律的题目啊 import java.util.Scanner; /** * Created by Pan on 2017/8/6. */ public class Main{ public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { int line = scanner.nextInt(); if (line <= 2) { System.out.println(-1); return; } if (line % 2 == 1) System.out.println(2); else { if ((line / 2) % 2 == 1) System.out.println(4); else System.out.println(3); } } } }
题目描述
现有一组砝码,重量互不相等,分别为m1,m2,m3…mn;
每种砝码对应的数量为x1,x2,x3...xn。现在要用这些砝码去称物体的重量,问能称出多少中不同的重量。
注:
称重重量包括0
方法原型:public static int fama(int n, int[] weight, int[] nums)
输入描述:
输入包含多组测试数据。
对于每组测试数据:
第一行:n --- 砝码数(范围[1,10])
第二行:m1 m2 m3 ... mn --- 每个砝码的重量(范围[1,2000])
第三行:x1 x2 x3 .... xn --- 每个砝码的数量(范围[1,6])
输出描述:
利用给定的砝码可以称出的不同的重量数
输入
2 1 2 2 1
输出
5
import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Scanner; import java.util.Set; /** * 1.称重 * @author bee * 思路: 以列为准,每一个遍历,然后加上新的值 */ public class Main{ public static void main(String[] args) { Scanner sc = new Scanner(System.in); while(sc.hasNext()) { Set<Integer> set = new LinkedHashSet<Integer>();//排序还去重复 int n = sc.nextInt(); int [] mg = new int[n]; int [] num = new int[n]; for(int i=0;i<n;i++){ mg[i]=sc.nextInt(); } for(int i=0;i<n;i++){ num[i]=sc.nextInt(); } for(int i=0;i<=num[0];i++){ set.add(mg[0]*i);//把第一列加上去 } for(int i=1;i<n;i++){//从第二个发麻开始 List<Integer>list =new ArrayList<Integer>(set);//这是之前能称重的 for(int j=1;j<=num[i];j++){//遍历砝码的个数 for(int k=0;k<list.size();k++) { set.add(list.get(k)+j*mg[i]); } } } System.out.println(set.size()); } sc.close(); } }
题目描述
请编写一个函数(允许增加子函数),计算n x m的棋盘格子(n为横向的格子数,m为竖向的格子数)沿着各自边缘线从左上角走到右下角,总共有多少种走法,要求不能走回头路,即:只能往右和往下走,不能往左和往上走。
输入描述:
输入两个正整数
输出描述:
返回结果
输入
2 2
输出
6
PS: 这个题完全不会
import java.util.*; public class Main { public static int find(int m, int n){ if(m == 0 || n == 0) return 1; else return find(m - 1, n) + find(m, n - 1); } public static void main(String[] args) { Scanner sc = new Scanner(System.in); while(sc.hasNext()){ int m = sc.nextInt(); int n = sc.nextInt(); System.out.println(find(m, n)); } sc.close(); } }
import java.util.*; public class Main { public static void main(String[] args){ Scanner in = new Scanner(System.in); while(in.hasNext()){ int n = in.nextInt(); int m = in.nextInt(); int[][] nm =new int[n+1][m+1]; for(int i=0;i<n;i++){ nm[i][m] = 1; } for(int i=0;i<m;i++){ nm[n][i] = 1; } for(int i=n-1;i>=0;i--){ for(int j=m-1;j>=0;j--){ nm[i][j] = nm[i+1][j]+nm[i][j+1]; } } System.out.println(nm[0][0]); } } }
题目描述
有6条配置命令,它们执行的结果分别是:
命 令 | 执 行 |
reset | reset what |
reset board | board fault |
board add | where to add |
board delet | no board at all |
reboot backplane | impossible |
backplane abort | install first |
he he | unkown command |
注意:he he不是命令。
为了简化输入,方便用户,以“最短唯一匹配原则”匹配:
1、若只输入一字串,则只匹配一个关键字的命令行。例如输入:r,根据该规则,匹配命令reset,执行结果为:reset what;输入:res,根据该规则,匹配命令reset,执行结果为:reset what;
2、若只输入一字串,但本条命令有两个关键字,则匹配失败。例如输入:reb,可以找到命令reboot backpalne,但是该命令有两个关键词,所有匹配失败,执行结果为:unkown command
3、若输入两字串,则先匹配第一关键字,如果有匹配但不唯一,继续匹配第二关键字,如果仍不唯一,匹配失败。例如输入:r b,找到匹配命令reset board,执行结果为:board fault。
4、若输入两字串,则先匹配第一关键字,如果有匹配但不唯一,继续匹配第二关键字,如果唯一,匹配成功。例如输入:b a,无法确定是命令board add还是backplane abort,匹配失败。
5、若输入两字串,第一关键字匹配成功,则匹配第二关键字,若无匹配,失败。例如输入:bo a,确定是命令board add,匹配成功。
6、若匹配失败,打印“unkown command”
输入描述:
多行字符串,每行字符串一条命令
输出描述:
执行结果,每条命令输出一行
输入
reset reset board board add board delet reboot backplane backplane abort
输出
reset what board fault where to add no board at all impossible install first
import java.util.*; public class Main{ public static void main(String[] args) { Scanner sc = new Scanner(System.in); while(sc.hasNext()){ String keys [] = {"reset","reset board", "board add","board delet", "reboot backplane", "backplane abort" }; String ans[] ={"reset what", "board fault", "where to add","no board at all","impossible","install first","unkown command" }; String str = sc.nextLine(); String[] cmds = str.split(" "); String result = "unkown command"; if(cmds.length==1){ for(int i=0;i<keys.length;i++){ if(keys[i].startsWith(str)){ String[] split = keys[i].split(" "); if(split.length==1){ result =ans[i]; break; }else{ result =ans[6]; } }else{ result =ans[6]; } } }else if(cmds.length==2){ String cmd1 = cmds[0]; String cmd2 = cmds[1]; int tt = 0; for(int i=0;i<keys.length;i++){ int count=0; String[] split = keys[i].split(" "); if(split.length==1){ }else{ if(split[0].startsWith(cmd1)){ count++; } if(split[1].startsWith(cmd2)){ count++; } } if(count==2){ result = ans[i]; tt++; } } if(tt>1){ result = ans[6]; } } System.out.println(result); } sc.close(); } }
题目描述
MP3 Player因为屏幕较小,显示歌曲列表的时候每屏只能显示几首歌曲,用户要通过上下键才能浏览所有的歌曲。为了简化处理,假设每屏只能显示4首歌曲,光标初始的位置为第1首歌。
现在要实现通过上下键控制光标移动来浏览歌曲列表,控制逻辑如下:
-
歌曲总数<=4的时候,不需要翻页,只是挪动光标位置。
光标在第一首歌曲上时,按Up键光标挪到最后一首歌曲;光标在最后一首歌曲时,按Down键光标挪到第一首歌曲。
其他情况下用户按Up键,光标挪到上一首歌曲;用户按Down键,光标挪到下一首歌曲。
2. 歌曲总数大于4的时候(以一共有10首歌为例):
特殊翻页:屏幕显示的是第一页(即显示第1 – 4首)时,光标在第一首歌曲上,用户按Up键后,屏幕要显示最后一页(即显示第7-10首歌),同时光标放到最后一首歌上。同样的,屏幕显示最后一页时,光标在最后一首歌曲上,用户按Down键,屏幕要显示第一页,光标挪到第一首歌上。
一般翻页:屏幕显示的不是第一页时,光标在当前屏幕显示的第一首歌曲时,用户按Up键后,屏幕从当前歌曲的上一首开始显示,光标也挪到上一首歌曲。光标当前屏幕的最后一首歌时的Down键处理也类似。
其他情况,不用翻页,只是挪动光标就行。
输入描述:
输入说明:
1 输入歌曲数量
2 输入命令 U或者D
输出描述:
输出说明
1 输出当前列表
2 输出当前选中歌曲
输入
10 UUUU
输出
7 8 9 10 7
PS: 学会了队列的使用,
q.offer()入队;
q.poll();出队
q.peek()获取栈顶元素
import java.util.*; public class Main{ public static void main(String[] args) { Scanner sc = new Scanner(System.in); while(sc.hasNext()){ Queue<Integer> queue = new LinkedList<Integer>();//队列 int n = Integer.parseInt(sc.nextLine()); String cmd = sc.nextLine(); int cur = 1; for(int i=0;i<cmd.length();i++){ if(n<=4){ if(queue.size()==0){ for(int j=1;j<=n;j++){ queue.offer(j);//初始化队列 } } if(cmd.charAt(i)==\'D\'){ cur++; if(cur>n){ cur = 1; } }else if(cmd.charAt(i)==\'U\'){ cur--; if(cur<=0){ cur =n; } } }else{//大于4个 if(queue.size()==0){ for(int j=1;j<=4;j++){ queue.offer(j);//初始化队列 } } if(cmd.charAt(i)==\'U\'){ cur--; if(cur<=0){//特殊 cur =n; queue.clear(); for(int j=cur-3;j<=cur;j++){ queue.offer(j);//更新队列 } continue; }else{//一般的U if((queue.peek()-cur)==1){ queue.clear(); for(int j=cur;j<=cur+3;j++){ queue.offer(j);//跟新队列 } } } }else if(cmd.charAt(i)==\'D\'){ cur++; if(cur>n){//特殊的D cur = 1; queue.clear(); for(int j=1;j<=4;j++){ queue.offer(j);//跟新队列 } }else{ if((cur-queue.peek()-3)==1){ queue.poll();//出队 queue.offer(cur); } } } } } String result=""; for (Integer x : queue) { result+=x+" "; } System.out.println(result.substring(0,result.length()-1)); System.out.println(cur); } sc.close(); } }
题目描述
定义一个二维数组N*M(其中2<=N<=10;2<=M<=10),如5 × 5数组下所示:
int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 0, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。入口点为[0,0],既第一空格是可以走的路。
Input
一个N × M的二维数组,表示一个迷宫。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。
Output
左上角到右下角的最短路径,格式如样例所示。
Sample Input
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
Sample Output
(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)
输入描述:
输入两个整数,分别表示二位数组的行数,列数。再输入相应的数组,其中的1表示墙壁,0表示可以走的路。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。
输出描述:
左上角到右下角的最短路径,格式如样例所示。
输入
5 5 0 1 0 0 0 0 1 0 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)
PS:这道题别人是用 深度 和广度优先算法实现的 ,我用的A*
import java.util.*; public class Main{ public static void main(String[] args) { Scanner sc = new Scanner(System.in); while(sc.hasNext()){ int m = sc.nextInt(); int n = sc.nextInt(); int [][] arr = new int[m][n]; for(int i=0;i<m;i++){ for(int j=0;j<n;j++){ arr[i][j] = sc.nextInt(); } } ArrayList<Node> search = getRoadCount(arr,0, 0, m-1, n-1); for(int i=0;i<search.size();i++) { System.out.println("("+search.get(i).getX()+","+search.get(i).getY()+")"); } } sc.close(); } public static ArrayList<Node> getRoadCount(int [][] map,int x1,int y1,int x2,int y2) { int[][] vitualMap = endAndEntranceToFinal(map,y2,x2);// y ,x AStar aStar=new AStar(vitualMap, vitualMap.length, vitualMap[0].length); //H W ArrayList<Node> resultList = aStar.search(x1, y1, x2, y2); //,y1 x1 ,x2,y2 return resultList; } /** * 把地图进行转换,从出口到指定的车位,除下指定车位不是障碍,其余都是 x,y是指定的车位 * 0,是障碍,1是路 * @param map * @return */ private static int[][] endAndEntranceToFinal(int [][] map,int x,int y) { int[][] result = new int[map.length][map[0].length]; for (int i = 0; i < map.length; i++) { for (int j = 0; j < map[0].length; j++) { if(map[i][j]==0){ result[i][j] = 1; }else{ result[i][j] = 0; } } } return result; } } class AStar { private int[][] map;// 地图(1可通过 0不可通过) private List<Node> openList;// 开启列表 private List<Node> closeList;// 关闭列表 private final int COST_STRAIGHT = 10;// 垂直方向或水平方向移动的路径评分 private final int COST_DIAGONAL = 14;// 斜方向移动的路径评分 private int row;// 行 private int column;// 列 public AStar(int[][] vitualMap, int row, int column) { this.map = vitualMap; this.row = row; [华为机试练习题]1.周期串问题华为OD机试真题Java实现单词反转真题+解题思路+代码(2022&2023)