1. 程式人生 > 其它 >傳智杯第一屆 真題解析 Jaca

傳智杯第一屆 真題解析 Jaca

技術標籤:java演算法資料結構dfs

例題一

從古至今,各種末日謠言層出不窮。假如現在有這樣一個謠言:天文學家在2014年6月1日,發現一顆行星,根據該行星的執行軌道,在3000天以後,該行星將撞擊地球。現在,請編寫Java程式計算,該謠言指向的“世界末日”是哪一天?

要求輸出格式為:xxxx-xx-xx(例如:2015-12-12),不要新增任何其他多餘文字。

輸出描述:
計算的結果日期,格式為:xxxx-xx-xx


輸出樣例:
2015-12-12

思路

一開始我想硬算髮現有點麻煩,然後看了下大佬的題解,才曉得
還有Data類,記住了

大佬連結

import java.util.Calendar;
import java.util.Date; public class Answer1 { public static void main(String[] args) { int year=2014;//date的輸出為1900年到現在的年數,因此需要具體年份時需要+1900 int month=6;//需要注意,在呼叫calendar或date類的方法時,輸入或輸出的月份均為0-11 int day=1; int add=3000; //1.呼叫calendar的add方法 Calendar calendar = Calendar.getInstance(); calendar.
set(year, month-1, day); calendar.add(Calendar.DATE, add); System.out.println(calendar.get(Calendar.YEAR)+"-"+(calendar.get(Calendar.MONTH)+1) +"-"+calendar.get(Calendar.DATE)); //2.直接用calendar設定增加後的日,進行輸出 Calendar calendar1 = Calendar.getInstance(); calendar1.set(
year, month-1, day+add); System.out.println(calendar.get(Calendar.YEAR)+"-"+(calendar.get(Calendar.MONTH)+1) +"-"+calendar.get(Calendar.DATE)); //3.直接用calendar設定增加後的日,再呼叫date格式化 Date date = new Date(year, month-1, day+add); System.out.println(date.getYear()+"-"+(date.getMonth()+1)+"-"+date.getDate()); } }

答案:2015-12-01

例題二

由1到n的平方個數字組成的n×n階方陣(n為任意給定的一個不小於3的奇數),它的每行、每列及對角線上的數字和都相等,稱為n階魔方陣。它的每行、每列及對角線上的數字和為n×(n² + 1) / 2。該方陣的排列方法是:

(1) 將數字1放在第一行的中間位置上,即(0,n/2)位置;
(2) 下一個數放在當前位置(i, j)的上一行(i-1)、下一列(j+1),即當前位置的右上方;如果出現以下情況,則修改填充位置:
① 若當前位置是第一行,下一個數放到最後一行,即把i-1修改為n-1;
② 若當前位置是最後一列,下一個數放在第一列,即把j-1修改為n-1;
③ 若下一個數要放的位置已經有數字,則下一個數放在當前位置的下一行,相同列。
(3) 重複以上過程,直到n²個數字不重複的填入方陣中。
根據以上描述,請使用Java語言,設計一個程式,輸出n階魔方陣。

輸入描述:

一個大於等於3的奇數n,不建議太大,3-9即可

輸出描述:

一個n*n的數字矩陣,每行的數字之間採用一個製表符"\t"分隔

輸入樣例:
3
輸出樣例:
8 1 6
3 5 7
4 9 2
無腦照題目模擬一下,寫完之後看大佬寫的,發現其實
整個就是:下一個數在當前數的右上方,如果超出了正方
形範圍就取摸,如果右上方有數字已經放了,就放在當
前數的正下方

無腦模擬

package 傳智杯第一屆;

import java.util.Scanner;

public class No2 {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        int n=input.nextInt();
        int [][]arr=new int[n][n];
        int j=(n/2);
        int i=0;
        for(int m=1;m<=n*n;m++){
            arr[i][j]=m;
            /*
             下一個數放在當前位置(i, j)的上一行(i-1)、下一列(j+1),即當前位置的右上方;如果出現以下情況,則修改填充位置:
              若當前位置是第一行,下一個數放到最後一行,即把i-1修改為n-1;
             */

            if(i==0&&arr[n-1][(j+1+n)%n]==0){
                i=n-1;
                j=(j+1+n)%n;

            }
            //②若當前位置是最後一列,下一個數放在第一列,即把j-1修改為n-1;
           else if(j==n-1&&arr[(i-1+n)%n][0]==0){
                i=(i-1+n)%n;
                j=0;
            }
           //③ 若下一個數要放的位置已經有數字,則下一個數放在當前位置的下一行,相同列。
           else if(arr[(i-1+n)%n][(j+1+n)%n]!=0){
               i=(i+1+n)%n;

            }
           else {
                i=(i-1+n)%n;
                j=(j+1+n)%n;
            }
        }
        for(int m=0;m<n;m++){
            for(int k=0;k<n;k++){
                System.out.print(arr[m][k]+"\t");
            }
            System.out.println();

        }
    }
}

大佬簡易程式碼

import java.util.Scanner;

public class Answer2 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n=sc.nextInt();
		int num[][]=new int[n][n];
		int i=0;
		int j=n/2;
		int k=1;
		while(k<=n*n){
			if (num[i][j]==0) {
				num[i][j]=k++;
				i=(i-1+n)%n;
				j=(j+1+n)%n;
			}else {
				i=(i+1+n)%n;
			}
		}
		for (i = 0; i < n; i++) {
			for(j=0;j<n;j++){
				System.out.print(num[i][j]+"\t");
			}
			System.out.println();
		}
	}
}

例題三

從前,某國王在處決500名死囚犯時突發奇想,想赦免其中的一個人,於是他把這500個死囚犯從1到500編號,都放到一片空地上,讓大家手牽手組成一個大環。從1號開始報數,凡是報數為3的倍數的人就要被殺掉,每輪過後,剩下的人組成一個較小的環,繼續報數(注意,上一輪最後一人報數後,下一輪的第一個人要繼續往下報,而不是重新從1開始),直到剩下最後一個人為止。請編寫程式計算,最終這個幸運的人是幾號?

輸出描述:

一個整數,表示最終活下來的人員編號

輸出樣例:

55

思路阿瑟夫環問題

import java.util.Scanner;

public class No3{
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);

        int n=500;
        int m=3;
        int res=0;

        for(int i=2;i<=n;i++){
            res=(res+m)%i;
        }
        System.out.println(res+1);
}
}

答案:436

例題四

給定一個正整數m(m最小是一個兩位數),現在想從組成m這個數的數字中,去掉其中的n個數字(0 < n < m的位數),但保持每位上的數字相對順序不變,使得剩餘的數字組成的數是最大值。例如:
當m = 51342,n = 1;則結果應該是去掉數字1,剩餘的值最大,為5342;
當m = 51342,n = 2;則結果應該是去掉數字1、3,剩餘的值最大,為542;
當m = 51342,n = 3;則結果應該是去掉數字1、3、2,剩餘的值最大,為54;

請使用Java語言程式設計,實現該演算法。其中的m和n按要求輸入正確範圍內的數字即可,無需做合法校驗。

輸入描述:
第一行輸入正整數m(m >= 10)
第二行輸入去掉的數字個數n(0 < n < m的位數)
輸出描述:
去掉n個數字後的最大值

輸入樣例:
51342
2
輸出樣例:
542

思路:

dfs 遞迴實現組合型列舉 類似於給定一個數,從中從前往後
選取n個數,湊成一個新的數,求這個數的最大值
import java.util.Scanner;

public class No4 {
    static int Max=-1;
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        String m=input.next();
        int n=input.nextInt();
        char []temp=m.toCharArray();
        int nn=m.length()-n;
        int []vis=new int[nn];
        String []arr=new String[nn];
        dfs(arr,nn,0,temp,0);
        System.out.println(Max);


    }
    public static void dfs(String []arr,int n,int level,char []temp,int next){
        if(level>=n){
            String tempsum="";
            for(int i=0;i<n;i++){
                tempsum+=arr[i];

            }
            int sum=Integer.parseInt(tempsum);
            if(sum>Max)
                Max=sum;

            return;
        }
        for(int i=next;i<temp.length;i++ ){
            arr[level]=temp[i]+"";
            dfs(arr,n,level+1,temp,i+1);

        }


    }
}

例題五

小智拿到一個數列{a1, a2, …, an},現在他想從這個數列中取出若干數,組成一個新的數列{ai1, ai2, …, aim},其中索引i1, i2, …, im保持遞增,也就是說數列中各個數仍然保持在原數列中的先後順序。並且在新數列中,對於任意索引ix > iy,都有aix > aiy,也就是說新數列是一個遞增的子序列。

請編寫程式,求出符合上述要求的最長遞增子序列的長度。

例如數列[1, 3, 6, 7, 9, 4, 10, 5, 6],最長遞增子序列為[1, 3, 6, 7, 9, 10],長度是6。

輸入描述:

任意個數的整數,中間使用空格分隔
輸出描述:

一個整數,表示符合題目要求的最長子序列的長度

輸入樣例:

1 3 6 7 9 4 10 5 6

輸出樣例:

6

思路

簡單的dp,最長上升子序列問題

import java.util.Scanner;

public class No5 {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        String In=input.nextLine();
        String arrtemp[]=In.split("\\s+");
        int n=arrtemp.length;
        int []arr=new int[n+1];
        int []dp=new int[n+1];
        for(int i=0;i<n;i++){
            arr[i]=Integer.parseInt(arrtemp[i]);
        }
        int ans=0;
        for(int i=0;i<n;i++){
            dp[i]=1;
            for(int j=0;j<i;j++){
                if(arr[i]>arr[j])
                    dp[i]=Math.max(dp[i],dp[j]+1);

            }
            ans=Math.max(dp[i],ans);
        }
        System.out.print(ans);
    }
}