2018級《算法分析與設計》練習7(Java)
問題 A: 數字交換
題目描述
輸入一個數n,然後輸入n個數值各不相同,調換數組中最大和最小的兩個數,然後輸出。
輸入
測試數據有多組,輸入n(1<=n<=20),接着輸入n個數。
輸出
對於每組輸入,輸出交換後的結果。
樣例輸入 Copy
2
1 3
樣例輸出 Copy
3 1
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
while(cin.hasNext()) {
int n=cin.nextInt();
int M = 0,N = 0;
int arr[]=new int[n];
int Min = 0,Max = 0,MinIndex = 0,MaxIndex = 0,temp;
for(int i=0;i<n;i++) {
arr[i]=cin.nextInt();
}
for(int i=0;i<n;i++) {
if(i == 0){
Min = arr[i];
Max = arr[i];
MinIndex = i;
MaxIndex = i;
}
if(Min > arr[i]){
Min = arr[i];
MinIndex = i;
}
if(Max < arr[i]){
Max = arr[i];
MaxIndex = i;
}
}
temp = arr[MinIndex];
arr[MinIndex] = arr[MaxIndex];
arr[MaxIndex] = temp;
for(int i = 0;i < n;i++){
System.out.print(arr[i]);
if(i != n-1){
System.out.print(" ");
}
}
System.out.println();
}
}
}
問題 B: 習題6-6 楊輝三角
題目描述
按要求輸出如下格式的楊輝三角
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
最多輸出10層。
輸入
輸入只包含一個正整數n,表示將要輸出的楊輝三角的層數。
輸出
對應於該輸入,請輸出相應層數的楊輝三角,每一層的整數之間用一個空格隔開。
樣例輸入 Copy
5
樣例輸出 Copy
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
while(cin.hasNext()) {
int n=cin.nextInt();
int arr[][]=new int[n+1][n+1];
for(int i=1;i<=n;i++) {
for(int j=1;j<=i;j++) {
if(i==1||j==1||j==i) {
arr[i][j]=1;
}else {
arr[i][j]=arr[i-1][j]+arr[i-1][j-1];
}
}
}
for(int i=1;i<=n;i++) {
for(int j=1;j<=i;j++) {
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
}
}
問題 C: 放蘋果
題目描述
把M個同樣的蘋果放在N個同樣的盤子裏,允許有的盤子空着不放,問共有多少種不同的分法?
(用K表示)5,1,1和1,5,1 是同一種分法。
輸入
每行均包含二個整數M和N,以空格分開。1<=M,N<=10。
輸出
對輸入的每組數據M和N,用一行輸出相應的K。
樣例輸入 Copy
7 3
樣例輸出 Copy
8
import java.util.Scanner;
public class Main {
public static int digui(int m,int n) {
if(m==0||n==1) {return 1;}
if(n>m) {return digui(m,m);}
return digui(m,n-1)+digui(m-n,n);
}
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
while(cin.hasNext()) {
int m=cin.nextInt();//panzi
int n=cin.nextInt();//pingguo
int k=0;
k=digui(m,n);
System.out.println(k);
}
}
}
問題 D: 小白鼠
題目描述
N只小白鼠(1 <= N <= 100),每隻鼠頭上戴着一頂有顏色的帽子。
現在稱出每隻白鼠的重量,要求按照白鼠重量從大到小的順序輸出它們頭上帽子的顏色。
帽子的顏色用“red”,“blue”等字符串來表示。
不同的小白鼠可以戴相同顏色的帽子。白鼠的重量用整數表示。
輸入
多案例輸入,每個案例的輸入第一行爲一個整數N,表示小白鼠的數目。
下面有N行,每行是一隻白鼠的信息。第一個爲不大於100的正整數,表示白鼠的重量;
第二個爲字符串,表示白鼠的帽子顏色,字符串長度不超過10個字符。
注意:白鼠的重量各不相同。
輸出
每個案例按照白鼠的重量從大到小的順序輸出白鼠的帽子顏色。
樣例輸入 Copy
3
30 red
50 blue
40 green
樣例輸出 Copy
blue
green
red
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
while(cin.hasNext()) {
int n=cin.nextInt();
int w[]=new int [n];
String c[]=new String[n];
for(int i=0;i<n;i++) {
w[i]=cin.nextInt();
c[i]=cin.next();
}
for(int i=0;i<n;i++) {
for(int j=i+1;j<n;j++) {
if(w[i]<w[j]) {
int t=w[i];
w[i]=w[j];
w[j]=t;
String color=c[i];
c[i]=c[j];
c[j]=color;
}
}
}
for(int i=0;i<n;i++) {
System.out.println(c[i]);
}
}
}
}
問題 E: 數字三角形之備忘錄法
題目描述
如下圖所示的數字三角形,從三角形的頂部到底部有很多條不同的路徑。對於每條路徑,把路徑上面的數加起來可以得到一個和,和最大的路徑稱爲最佳路徑。編寫一個程序求出最佳路徑上的數字之和。 【使用備忘錄法實現】
7
3 8
8 1 2
2 7 4 4
4 5 2 6 5
輸入
多組樣例輸入,每組第一行輸入三角形的層數n,接下來n行輸入三角形。
輸出
輸出最佳路徑上的數字之和。
樣例輸入 Copy
2
1
1 2
3
1
1 2
1 2 3
樣例輸出 Copy
3
6
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
static int dp[][]=new int [105][105];
static int arr[][]=new int[105][105];
static int n;
public static int f(int i,int j) {
if(dp[i][j]>=0) return dp[i][j]; //引入備忘錄保存子問題的解
if(i==n+1) return 0;
return dp[i][j]=arr[i][j]+Math.max(f(i+1,j),f(i+1,j+1));
}
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
while(cin.hasNext()) {
n=cin.nextInt();
for(int i=1;i<=n;i++) {
for(int j=1;j<=i;j++) {
arr[i][j]=cin.nextInt();
dp[i][j]=-1;
}
}
System.out.println(f(1,1));
}
}
}
問題 F: 數字三角形之動態規劃法
題目描述
如下圖所示的數字三角形,從三角形的頂部到底部有很多條不同的路徑。對於每條路徑,把路徑上面的數加起來可以得到一個和,和最大的路徑稱爲最佳路徑。編寫一個程序求出最佳路徑上的數字之和。 【使用動態規劃法實現】
7
3 8
8 1 2
2 7 4 4
4 5 2 6 5
輸入
多組樣例輸入,每組第一行輸入三角形的層數n,接下來n行輸入三角形。
輸出
輸出最佳路徑上的數字之和。
樣例輸入 Copy
2
1
1 2
3
1
1 2
1 2 3
樣例輸出 Copy
3
6
提示
路徑上的每一步只能從一個數走到下一層上和它最近的左邊的數或者右邊的數。
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
while(cin.hasNext()) {
int n=cin.nextInt();
int arr[][]=new int[n+1][n+1];
int f[][]=new int[n+1][n+1];
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
arr[i][j]=cin.nextInt();
}
}
for(int i=1;i<=n;i++){
f[n][i]=arr[n][i];
}
for(int i=n-1;i>=1;i--){
for(int j=1;j<=i;j++){
f[i][j]=Math.max(f[i+1][j],f[i+1][j+1])+arr[i][j];
}
}
System.out.println(f[1][1]);
}
}
}
問題 G: 最長公共子序列問題(LCS)之備忘錄法
題目描述
使用備忘錄法求解兩個序列的最長公共子序列的長度。
輸入
每組輸入包括兩行,每行包括一個字符串。
輸出
兩個序列的最長公共子序列的長度。
樣例輸入 Copy
ACBCDABD
ABDCABA
樣例輸出 Copy
5
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
static int dp[][]=new int [105][105];
static int arr[][]=new int[105][105];
public static int f(char arr1[],char arr2[],int n,int m) {
if(n==0||m==0) {
return 0;
}else if(arr1[n-1]==arr2[m-1]) {
dp[n][m]=f(arr1,arr2,n-1,m-1)+1;
}else {
dp[n][m]=Math.max(f(arr1,arr2,n-1,m),f(arr1,arr2,n,m-1));}
return dp[n][m];
}
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
while(cin.hasNext()) {
String a=cin.next();
String b=cin.next();
char[] arr1=a.toCharArray();
char[] arr2=b.toCharArray();
System.out.println(f(arr1,arr2,arr1.length,arr2.length));
}
}
}
問題 H: 整數劃分問題之備忘錄法
題目描述
使用備忘錄法編寫一個程序,求一個正整數n的所有劃分個數。
例如,輸入3,輸出3;輸入4,輸出5。
輸入
多組輸入,每一組是一個正整數n。
輸出
輸出劃分數。
樣例輸入 Copy
3
4
樣例輸出 Copy
3
5
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
static int dp[][]=new int[105][105];
static int n;
public static int f(int n,int m) {
if((n<1)||(m<1)) return 0;
if((n==1)||(m==1)) return 1;
if(n<m) return f(n,n);
if(n==m) {
if (dp[n-1][n-2]==0) {
dp[n-1][n-2] = f(n,n-1);
}
return 1 + dp[n-1][n-2];
}
if (n>m) {
if (dp[n-1][m-2]==0) {
dp[n-1][m-2] = f(n,m-1);
}
if (dp[n-m-1][m-1]==0) {
dp[n-m-1][m-1]=f(n-m,m);
}
return dp[n-1][m-2] + dp[n-m-1][m-1];
}else {return 0;}
}
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
while(cin.hasNext()) {
n=cin.nextInt();
System.out.println(f(n,n));
}
}
}