我參加的機試是昨天晚上19:00到21:00,三道編程題目
由於考試期間在牛客網需要錄屏所以沒辦法得到准確題目(華為允許使用本地IDE),我只能按照記憶描述
題目1
大概意思是:有n個人,每一個人都有一種禮物(禮物種類有兩種,1是A類,2是B類),求三個人禮物數量(同種類)相加和最大,如果存在多組則輸出序號小的那一組。如果不存在輸出字符串"null"
輸入:第一行n,后面n行就是每個人所擁有的禮物數目和禮物種類
輸出:第一行3個人的序號(處於第幾行就是該人的序號),第二行禮物種類,第三行禮物數目最多是多少
輸入樣例:
6
2 2
2 1
3 2
5 2
3 1
7 2
輸出樣例:
3 4 6
2
15
解釋:此樣例選了第3、4、6行,都是種類2,禮物數目是3+5+7=15
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 []num = new int[n];
int []type = new int[n];
int cnt =0;
for(int i=0;i<n;i++){
num[i]=sc.nextInt();
type[i]=sc.nextInt();
if(type[i]==1) cnt++;
}
//四個數組可以用兩個treemap代替
int []n1 =new int[cnt];
int[]t1 = new int[cnt];
int[] n2 = new int[n-cnt];
int[] t2 = new int[n-cnt];
int top1=0,top2=0,t11=0,t22=0;
for(int i=0;i<n;i++){
if(type[i]==1){
n1[top1++] = num[i];
t1[t11++] = i+1;//注意這里是從第1行開始的
}else if(type[i]==2){
n2[top2++] = num[i];
t2[t22++] = i+1;
}
}
if(cnt<3&&n-cnt<3) {//沒滿足情況
System.out.println("null");continue;
}
if(cnt < 3){
helper(n2,t2);
System.out.println(t2[t2.length-3]+" "+t2[t2.length-2]+" "+t2[t2.length-1]);
System.out.println(2);
System.out.println(n2[n2.length-1]+n2[n2.length-2]+n2[n2.length-3]);
}
else if(n-cnt<3){
helper(n1,t1);
System.out.println(t1[t1.length-3]+" "+t1[t1.length-2]+" "+t1[t1.length-1]);
System.out.println(1);
System.out.println(n1[n1.length-1]+n1[n1.length-2]+n1[n1.length-3]);
}else{//兩個種類禮物的人都>=3
helper(n2,t2);
helper(n1,t1);
if(n2[n2.length-1]+n2[n2.length-2]+n2[n2.length-3] > n1[n1.length-1]+n1[n1.length-2]+n1[n1.length-3]){//比較總量誰大
System.out.println(t2[t2.length-3]+" "+t2[t2.length-2]+" "+t2[t2.length-1]);
System.out.println(2);
System.out.println(n2[n2.length-1]+n2[n2.length-2]+n2[n2.length-3]);
}else if(n2[n2.length-1]+n2[n2.length-2]+n2[n2.length-3] < n1[n1.length-1]+n1[n1.length-2]+n1[n1.length-3]){
System.out.println(t1[t1.length-3]+" "+t1[t1.length-2]+" "+t1[t1.length-1]);
System.out.println(1);
System.out.println(n1[n1.length-1]+n1[n1.length-2]+n1[n1.length-3]);
}else{
if(t2[t2.length-3] > t1[t1.length-3]){//總量相等比較序號
System.out.println(t1[t1.length-3]+" "+t1[t1.length-2]+" "+t1[t1.length-1]);
System.out.println(1);
System.out.println(n1[n1.length-1]+n1[n1.length-2]+n1[n1.length-3]);
}else{
System.out.println(t2[t2.length-3]+" "+t2[t2.length-2]+" "+t2[t2.length-1]);
System.out.println(2);
System.out.println(n2[n2.length-1]+n2[n2.length-2]+n2[n2.length-3]);
}
}
}
}
public static void helper(int[] n,int[]t){//此過程完全可以用treemap自動完成
for(int i=0;i<n.length;i++){
for (int j = 0; j <n.length-i-1 ; j++) {
if(n[j]>n[j+1]){
int t1 = n[j];
n[j] = n[j+1];
n[j+1]=t1;
int x = t[j];
t[j] = t[j+1];
t[j+1] = x;
}
}
}
}
}
}
這道題其實可以用treemap進行排序,不用進行我這樣,treemap我用的不是很多機考時忘了。。。。。。
通過率:100%
題目2
這道題目我見過類似的,輸入矩陣的行和列,接下來輸入字符矩陣,H代表陸地,S代表水池,被H或者邊界包圍的S算成有一個水池,讓你計算有多少個水池
例如:
輸入樣例
3,5
SSHHH
SSHSH
HHHHS
輸出樣例:
3
我的思路:深搜,當找到一個S時讓它向四個方向走,遇到S變成H,這樣當遍歷到水池中的一個第一個S時,同一水池的其它S都變成H了,所以只需要統計S的數目就可以了。
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String[] strs= sc.nextLine().split(",");
int m = Integer.valueOf(strs[0]);
int n = Integer.valueOf(strs[1]);
String[] map = new String[m];
char[][] map1 = new char[m][n];
for(int i=0;i<m;i++){
map[i] = sc.nextLine();
}
for(int i=0;i<m;i++){
for (int j = 0; j <n ; j++) {
map1[i][j] = map[i].charAt(j);
}
}
int res = 0;
for(int i=0;i<m;i++){
for (int j = 0; j < n; j++) {
if(map1[i][j] == 'S'){
dfs(map1,i,j,m,n);
res++;
}
}
}
System.out.println(res);
}
}
public static void dfs(char[][] map,int i,int j,int m,int n){
if(i<0||i>=m||j<0||j>=n ||map[i][j]=='H') return;
if(map[i][j]=='S') map[i][j] = 'H';
dfs(map,i+1,j,m,n);
dfs(map,i,j+1,m,n);
dfs(map,i-1,j,m,n);
dfs(map,i,j-1,m,n);
}
}
通過率:80%,說是有數組越界,我沒檢查出來,思路就是這樣
題目3
這道題經典的01背包問題,我一看不會想着就混通過率吧,題目還是簡單說一下,題目描述有一個卡車空間k,有n個物品,物品有它的大小和價值,問你如何將物品放到卡車中保證他的價值最大。
輸入就是:n k 兩個價值和大小的數組
輸出:最大價值
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
int k = sc.nextInt();
int n =sc.nextInt();
int []size = new int[n];
int[] value =new int[n];
//double []perV = new double[n];
for (int i = 0; i <n ; i++) {
size[i] = sc.nextInt();
}
for (int i = 0; i <n ; i++) {
value[i] = sc.nextInt();
//perV[i] = value[i]*1.0/size[i];
}
helper(size,value);
int res = 0;
for (int i = n-1; i >=0 ; i--) {
if(k - size[i] >= 0){
res += value[i];
k-=size[i];
}
}
for (int i = 0; i < n; i++) {
if(k - size[i] >= 0){
res += value[i];
k-=size[i];
}
}
System.out.println(res);
}
}
public static void helper(int[] size,int [] value){
for (int i = 0; i <size.length ; i++) {
for (int j = 0; j <size.length-1-i ; j++) {
if(value[j] > value[j+1]){
int v1 = value[j];
value[j] = value[j+1];
value[j+1] = v1;
int s1 = size[j];
size[j] = size[j+1];
size[j+1] = s1;
}
}
}
}
}
通過率:45.45%
我是通過貪心進行做的,我知道可以得到較優解,正確做法。。。。。。。
01背包//好像這個做法也只能過80%
下面代碼來源:https://www.cnblogs.com/TestAndDevelp/p/12378831.html
import java.util.*;
public class test {
public static int getMaxValue(int[] weight, int[] value, int w, int n) {
int[][] table = new int[n + 1][w + 1];
for (int i = 1; i <= n; i++) { //物品
for (int j = 1; j <= w; j++) { //背包大小
if (weight[i] > j) {
//當前物品i的重量比背包容量j大,裝不下,肯定就是不裝
table[i][j] = table[i - 1][j];
// System.out.print(table[i][j]+ " ");
} else { //裝得下,Max{裝物品i, 不裝物品i}
table[i][j] = Math.max(table[i - 1][j], table[i - 1][j - weight[i]] + value[i]);
//System.out.print(table[i][j]+ " ");
}
}
// System.out.println();
}
return table[n][w];
}
public static void main(String[] args) {
int n = 5, w = 10; //物品個數,背包容量
int[] value = {0, 6, 3, 5, 4, 6}; //各個物品的價值
int[] weight = {0, 2, 2, 6, 5, 4}; //各個物品的重量
System.out.println(getMaxValue(weight,value,w,n));
}
}