題目一:ISBN號碼
題目描述:
每一本正式出版的圖書都有一個ISBN號碼與之對應,ISBN碼包括9位數字、1位識別碼和3位分隔符,其規定格式如“x-xxx-xxxxx-x”,其中符號“-”是分隔符(鍵盤上的減號),最后一位是識別碼,例如0-670-82162-4就是一個標準的ISBN碼。ISBN碼的首位數字表示書籍的出版語言,例如0代表英語;第一個分隔符“-”之后的三位數字代表出版社,例如670代表維京出版社;第二個分隔之后的五位數字代表該書在出版社的編號;最后一位為識別碼。
識別碼的計算方法如下:
首位數字乘以1加上次位數字乘以2……以此類推,用所得的結果mod 11,所得的余數即為識別碼,如果余數為10,則識別碼為大寫字母X。例如ISBN號碼0-670-82162-4中的識別碼4是這樣得到的:對067082162這9個數字,從左至右,分別乘以1,2,…,9,再求和,即0×1+6×2+……+2×9=158,然后取158 mod 11的結果4作為識別碼。
你的任務是編寫程序判斷輸入的ISBN號碼中識別碼是否正確,如果正確,則僅輸出“Right”;如果錯誤,則輸出你認為是正確的ISBN號碼。
輸入輸出描述:
輸入:0-670-82162-4? ? ? ? ? ? ? ? 輸出:Right
輸入:0-670-82162-0? ? ? ? ? ? ? ? 輸出:0-670-82162-4
題目解析:
step1:首先將字符串轉化為字符數組,并統計字符串長度為n。
step2:遍歷整個除最后一個字符以外的字符數字,如果是數字,就乘以對應的位數,用sum統計累加之和。
step3:用ret=sum%11,如果計算出來的值與實際最后一個字符值相等,即s[n-1]-'0'==ret或者ret==10&&s[n-1]='X',返回Right;
如果不相等,更新s[n-1]的值,s[n-1]=(char) (ret==10?'X':ret+'0');并重新打印數組。
作答情況:
char類型轉化為int類型搞不清楚:將字符減一個‘0’;
int類型轉char類型:將數字加一個‘0’,并強制類型轉換為char。
代碼:
import java.util.Scanner;// 注意類名必須為 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);char[] s=in.next().toCharArray();int num=1;int sum=0;int n=s.length;int ret=0;for(int i=0;i<n-1;i++){if(s[i]>='0'&&s[i]<='9'){sum+=(s[i]-'0')*num;num++;}}ret=sum%11;//4if(ret==s[n-1]-'0'||ret==10&&s[n-1]=='X'){System.out.print("Right");}else{s[n-1]=(char) (ret==10?'X':ret+'0');for(int i=0;i<n;i++){System.out.print(s[i]);}}}
}
題目二:kotori和迷宮
題目描述:
kotori在一個n*m迷宮里,迷宮的最外層被巖漿淹沒,無法涉足,迷宮內有k個出口。kotori只能上下左右四個方向移動。她想知道有多少出口是她能到達的,最近的出口離她有多遠?
輸入輸出描述:
輸入描述:
第一行為兩個整數n和m,代表迷宮的行和列數 (1≤n,m≤30) 后面緊跟著n行長度為m的字符串來描述迷宮。'k'代表kotori開始的位置,'.'代表道路,'*'代表墻壁,'e'代表出口。保證輸入合法。
輸出描述:
若有出口可以抵達,則輸出2個整數,第一個代表kotori可選擇的出口的數量,第二個代表kotori到最近的出口的步數。(注意,kotori到達出口一定會離開迷宮)
若沒有出口可以抵達,則輸出-1。
題目解析:
step1:首先從鍵盤中讀入二維數組arr[i][j],如果遇到了起點' k ',記錄下起點的下標為x1,y1
step2:寫寬度優先搜索bfs(),統計到出口的距離。
step3:更新結果,用count統計出口個數,用ret記錄最小距離,遍歷整個數組,如果arr[i][j]=='e'(出口)而且dist[i][j]!=-1 (能走到出口位置),count++,并且更新ret
作答情況:
①二維數組從鍵盤中讀入,不會寫。
②如果bfs寬度優先遍歷的話,遍歷上下左右四個方向不知如何處理。
③構造二維數組來求距離沒有想到。
④沒有做過迷宮問題,初次做覺得有些難。
代碼:
import java.util.*;
public class Main{public static int N=35;public static int m,n;public static int x1,y1;public static char[][] arr=new char[N][N];public static int[][] dist=new int[N][N];public static int[] dx={0,0,-1,1};public static int[] dy={-1,1,0,0};public static void main(String[] args){Scanner in=new Scanner(System.in);m=in.nextInt();n=in.nextInt();for(int i=0;i<m;i++){char[] temp=in.next().toCharArray();for(int j=0;j<n;j++){arr[i][j]=temp[j];if(arr[i][j]=='k'){x1=i;y1=j;}
}}bfs();int count=0;int ret=1000;for(int i=0;i<m;i++){for(int j=0;j<n;j++){if(arr[i][j]=='e'&&dist[i][j]!=-1){count++;ret=Math.min(ret,dist[i][j]);}}}if(count==0) System.out.print(-1);else System.out.print(count+" "+ret);}
public static void bfs(){for(int i=0;i<m;i++){for(int j=0;j<n;j++){dist[i][j]=-1;}}Queue<int[]> q=new LinkedList<>();q.add(new int[]{x1,y1});dist[x1][y1]=0;while(!q.isEmpty()){int[] temp=q.poll();int a=temp[0]; int b=temp[1];for(int t=0;t<4;t++){int x=a+dx[t]; int y=b+dy[t];if(x>=0&&y>=0&&x<m&&y<n&&arr[x][y]!='*'&&dist[x][y]==-1){dist[x][y]=dist[a][b]+1;if(arr[x][y]!='e') q.add(new int[]{x,y});}}}}
}
題目三:矩陣最長遞增路徑
題目描述:
給定一個 n 行 m?列矩陣 matrix?,矩陣內所有數均為非負整數。 你需要在矩陣中找到一條最長路徑,使這條路徑上的元素是遞增的。并輸出這條最長路徑的長度。
這個路徑必須滿足以下條件:
1. 對于每個單元格,你可以往上,下,左,右四個方向移動。 你不能在對角線方向上移動或移動到邊界外。
2. 你不能走重復的單元格。即每個格子最多只能走一次。
輸入輸出描述:
輸入描述:
[[1,2,3],[4,5,6],[7,8,9]]
輸出描述:5(1->2->3->6->9)
題目解析:
核心采用深度優先搜索dfs()
step1:判斷特殊情況(空矩陣)
step2:兩層for循環遍歷每個節點并進行深度優先搜索dfs(),傳入的參數有:matrix,i,j,lastNum(上一個節點的值),len(路徑長度)
step3:dfs()方法的步驟:記錄當前的值準備遞歸——>將走過的路涂黑——>dfs四個方向——>回退記錄的值?
step4:在dfs四個方向時注意下標是否越界和遍歷到的值是否大于lastNum,這也是終止條件。
作答情況:
終止條件寫的時候,只考慮到下標越界沒有考慮到遍歷到的值是否大于lastNum。
代碼:
public class Main {public static int result;public static void main(String[] args) {Scanner in=new Scanner(System.in);int m=in.nextInt();int n=in.nextInt();int[][] matrix=new int[m][n];for(int i=0;i<m;i++){for(int j=0;j<n;j++){matrix[i][j]=in.nextInt();}}for(int i=0;i<m;i++){for(int j=0;j<n;j++){dfs(matrix,i,j,-1,0);}}System.out.println(result);}
private static void dfs(int[][] matrix, int i, int j, int lastNum, int len) {if(i<0||j<0||i>=matrix.length||j>=matrix[0].length||matrix[i][j]<lastNum){result=Math.max(result,len);return;}int temp=matrix[i][j];matrix[i][j]=-1;dfs(matrix,i+1,j,temp,len+1);dfs(matrix,i-1,j,temp,len+1);dfs(matrix,i,j+1,temp,len+1);dfs(matrix,i,j-1,temp,len+1);matrix[i][j]=temp;}
}
收獲:
①char類型轉化為int類型:將字符減一個‘0’;
int類型轉char類型:將數字加一個‘0’,并強制類型轉換為char。
②從鍵盤中讀入二維字符數組的寫法:
Scanner in=new Scanner(System.in);int m=in.nextInt();int n=in.nextInt();for(int i=0;i<m;i++){char[] temp=in.next().toCharArray();for(int j=0;j<n;j++){arr[i][j]=temp[j];}}
③②從鍵盤中讀入二維整形數組的寫法:
Scanner in=new Scanner(System.in);int m=in.nextInt();int n=in.nextInt();int[][] matrix=new int[m][n];for(int i=0;i<m;i++){for(int j=0;j<n;j++){matrix[i][j]=in.nextInt();}}
?
?