演算法每日學打卡:01-21打卡(解答後面整理)

程式設計師歐陽思海發表於2018-06-26

“演算法每日學”計劃01打卡: 問題描述 對於長度為5位的一個01串,每一位都可能是0或1,一共有32種可能。它們的前幾個是: 00000 00001 00010 00011 00100 請按從小到大的順序輸出這32種01串。 輸入格式 本試題沒有輸入。 輸出格式 輸出32行,按從小到大的順序每行一個長度為5的01串。 樣例輸出 00000 00001 00010 00011 <以下部分省略>

1

“演算法每日學”計劃02打卡: 問題描述   十六進位制數是在程式設計時經常要使用到的一種整數的表示方式。它有0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F共16個符號,分別表示十進位制數的0至15。十六進位制的計數方法是滿16進1,所以十進位制數16在十六進位制中是10,而十進位制的17在十六進位制中是11,以此類推,十進位制的30在十六進位制中是1E。   給出一個非負整數,將它表示成十六進位制的形式。 輸入格式   輸入包含一個非負整數a,表示要轉換的數。0<=a<=2147483647 輸出格式   輸出這個整數的16進製表示 樣例輸入 30 樣例輸出 1E

2

“演算法每日學”計劃03打卡: 問題描述   陣列中有一個數字出現的次數超過陣列長度的一半,請找出這個數字。   例如輸入一個長度為9的陣列{1,2,3,2,2,2,5,4,2}。由於數字2在陣列中出現了5次,超過陣列長度的一半,因此輸出2。 輸入格式   每個測試案例包括2行:   第一行輸入一個整數n(1<=n<=100000),表示陣列中元素的個數。   第二行輸入n個整數,表示陣列中的每個元素,這n個整數的範圍是[1,1000000000]。 輸出格式   對應每個測試案例,輸出出現的次數超過陣列長度的一半的數,如果沒有輸出-1。 樣例輸入 9 1 2 3 2 2 2 5 4 2 9 1 1 1 2 2 2 3 3 3 樣例輸出 2 -1

3

“演算法每日學”計劃04打卡: 問題描述     在一個二維陣列中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。   請完成一個函式,輸入這樣的一個二維陣列和一個整數,判斷陣列中是否含有該整數。 輸入  輸入可能包含多個測試樣例,對於每個測試案例,   輸入的第一行為兩個整數m和n(1<=m,n<=1000):代表將要輸入的矩陣的行數和列數。   輸入的第二行包括一個整數t(1<=t<=1000000):代表要查詢的數字。   接下來的m行,每行有n個數,代表題目所給出的m行n列的矩陣(矩陣如題目描述所示,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。 輸出 對應每個測試案例,   輸出”Yes”代表在二維陣列中找到了數字t。   輸出”No”代表在二維陣列中沒有找到數字t。 樣例輸入 3 3 5 1 2 3 4 5 6 7 8 9 3 3 1 2 3 4 5 6 7 8 9 10 樣例輸出 YES NO

4

“演算法每日學”計劃05打卡: 問題描述     理論知識學習,演算法基礎,理解時間複雜度,理解空間複雜度。 輸入  無 輸出 無      5

"演算法每日學計劃"06打卡: 問題描述   給定一個長度為n的數列,將這個數列按從小到大的順序排列。1<=n<=200 輸入格式   第一行為一個整數n。   第二行包含n個整數,為待排序的數,每個整數的絕對值小於10000。 輸出格式   輸出一行,按從小到大的順序輸出排序後的數列。 樣例輸入 5 8 3 6 4 9 樣例輸出 3 4 6 8 9 注:題目簡單,解法不少於10種,踴躍發言。

6

“演算法每日學計劃”07打卡: 問題描述   求出區間[a,b]中所有整數的質因數分解。 輸入格式   輸入兩個整數a,b。 輸出格式   每行輸出一個數的分解,形如k=a1a2a3…(a1<=a2<=a3…,k也是從小到大的)(具體可看樣例) 樣例輸入 3 10 樣例輸出 3=3 4=22 5=5 6=23 7=7 8=222 9=33 10=25 提示   先篩出所有素數,然後再分解。 資料規模和約定 2<=a<=b<=10000

7

“演算法每日學計劃”08打卡: 問題描述   給定兩個僅由大寫字母或小寫字母組成的字串(長度介於1到10之間),它們之間的關 系是以下4中情況之一:   1:兩個字串長度不等。比如 Beijing 和 Hebei   2:兩個字串不僅長度相等,而且相應位置上的字元完全一致(區分大小寫),比如 Beijing 和 Beijing   3:兩個字串長度相等,相應位置上的字元僅在不區分大小寫的前提下才能達到完 全一致(也就是說,它並不滿足情況2)。比如 beijing 和 BEIjing   4:兩個字串長度相等,但是即使是不區分大小寫也不能使這兩個字串一致。比 如 Beijing 和 Nanjing   程式設計判斷輸入的兩個字串之間的關係屬於這四類中的哪一類,給出所屬的類的編號 。 輸入格式   包括兩行,每行都是一個字串 輸出格式   僅有一個數字,表明這兩個字串的關係編號 樣例輸入 BEIjing beiJing 樣例輸出 3 注意:簡單題目

8

“演算法每日學計劃”09打卡: 問題描述   給定一個N階矩陣A,輸出A的M次冪(M是非負整數)   例如:   A =   1 2   3 4   A的2次冪   7 10   15 22 輸入格式   第一行是一個正整數N、M(1<=N<=30, 0<=M<=5),表示矩陣A的階數和要求的冪數   接下來N行,每行N個絕對值不超過10的非負整數,描述矩陣A的值 輸出格式   輸出共N行,每行N個整數,表示A的M次冪所對應的矩陣。相鄰的數之間用一個空格 隔開 樣例輸入 2 2 1 2 3 4 樣例輸出 7 10 15 22

9

“演算法每日學計劃”10打卡: 問題描述 亞洲微軟研究院所在的希格瑪大廈一共有6部電梯。在高峰時間,每層都有人上下,電梯在每層都停。實習生小飛常常會被每層都停的電梯弄得很不耐煩,於是他提出了這樣一個辦法: 由於樓層並不算太高,那麼在繁忙的上下班時間,每次電梯從一層往上走時,我們只允許電梯停在其中的某一層。所有乘客從一樓上電梯,到達某層後,電梯停下來,所有乘客再從這裡爬樓梯到自己的目的層。在一樓的時候,每個乘客選擇自己的目的層,電梯則自動計算出應停的樓層。 問:電梯停在哪一層樓,能夠保證這次乘坐電梯的所有乘客爬樓梯的層數之和最少。 問題分析 該問題本質上是一個優化問題。   首先為這個問題找到一個合適的抽象模型。 有兩個因素會影響結果:乘客的數目和乘客的目的樓層。

10

“演算法每日學”11打卡 問題描述:  寫一個演算法計算出n的階乘。 n! = n * (n - 1) * (n - 2) * ... * 3 * 2 * 1 1<=n<=10. 輸入: 任意一個數字n。 輸出: 數字n的階乘結果。

11

“演算法每日學計劃”12打卡: 問題描述   輸入一個只包含加減乖除和括號的合法表示式,求表示式的值。其中除表示整除。 輸入格式   輸入一行,包含一個表示式。 輸出格式   輸出這個表示式的值。 樣例輸入 1-2+3*(4-5) 樣例輸出 -4 資料規模和約定   表示式長度不超過100,表示式運算合法且運算過程都在int內進行。

#####解題思路: 注意:解答群裡的小夥伴提供的,感謝! 1,初始化兩個棧:運算子棧S1和儲存中間結果的棧S2; 2,從左至右掃描中綴表示式; 3,遇到運算元時,將其壓入S2,這裡由於運算數可能大於10,所以如果數字後面一個符號是運算子,則將‘#’入S2棧充當分割線; 4, 遇到運算子時有三種情況: (4-1) 三種情況下直接入S1棧①S1為空②運算子為‘(’③運算子優先順序比S1棧頂運算子的高; (4-2)如果右括號“)”,則依次彈出S1棧頂的運算子,並壓入S2,直到遇到左括號為止,此時將這一對括號丟棄; (4-3) 若運算子優先順序小於或等於S1棧頂運算子的優先順序,則依次彈出S1棧頂元素,直到運算子的優先順序大於S1棧頂運算子優先順序; 5, 重複步驟(2)至(5),直到表示式的最右邊; 6,將S1中剩餘的運算子依次彈出並壓入S2; 7,依次彈出S2中的元素並輸出,結果的逆序即為中綴表示式對應的字尾表示式

題解
import java.util.Scanner;
import java.util.Stack;
public class Main{
public static void main(String[] args) {

        // TODO Auto-generated method stub
        Scanner scanner = new Scanner(System.in);
        Stack<Integer> nums = new Stack<Integer>(); // 儲存數字
        Stack<Character> opes = new Stack<Character>(); // 儲存操作符

        String string = scanner.nextLine();
        int n = 0; // 儲存每一個數字
        char[] cs = string.toCharArray();

        for (int i = 0; i < cs.length; i++) {
            char temp = cs[i];
            if (Character.isDigit(cs[i])) {
                n = 10 * n + Integer.parseInt(String.valueOf(cs[i])); // 大於10的數字儲存
            } else {
                if (n != 0) {
                    nums.push(n);
                    n = 0;
                }
                if (temp == '(') {
                    opes.push(temp);
                } else if (temp == ')') {
                    while (opes.peek() != '(') { // 括號裡面運算完
                        int t = cal(nums.pop(), nums.pop(), opes.pop());
                        nums.push(t);
                    }
                    opes.pop();
                } else if (isType(temp) > 0) {
                    if (opes.isEmpty()) { // 棧為空直接入棧
                        opes.push(temp);
                    } else {
                        // 若棧頂元素優先順序大於或等於要入棧的元素,將棧頂元素彈出並計算,然後入棧
                        if (isType(opes.peek()) >= isType(temp)) {
                            int t = cal(nums.pop(), nums.pop(), opes.pop());
                            nums.push(t);
                        }
                        opes.push(temp);
                    }
                }
            }
        }

        // 最後一個字元若是數字,未入棧
        if (n != 0) {
            nums.push(n);
        }
        while (!opes.isEmpty()) {
            int t = cal(nums.pop(), nums.pop(), opes.pop());
            nums.push(t);
        }
        System.out.println(nums.pop());
    }

    // 返回的是運算子的優先順序,數字和()不需要考慮
    public static int isType(char c) {
        if (c == '+' || c == '-') {
            return 1;
        } else if (c == '*' || c == '/') {
            return 2;
        } else {
            return 0;
        }
    }

    // 運算次序是反的,跟入棧出棧次序有關
    public static int cal(int m, int n, char c) {
        int sum = -987654321;
        if (c == '+') {
            sum = n + m;
        } else if (c == '-') {
            sum = n - m;
        } else if (c == '*') {
            sum = n * m;
        } else if (c == '/') {
            sum = n / m;
        }
        return sum;
    }
}

複製程式碼

“演算法每日學計劃”13打卡: 問題描述   給兩組數,各n個。   請調整每組數的排列順序,使得兩組資料相同下標元素對應相乘,然後相加的和最小。要求程式輸出這個最小值。   例如兩組數分別為:1 3  -5和-2 4 1   那麼對應乘積取和的最小值應為:   (-5) * 4 + 3 * (-2) + 1 * 1 = -25 輸入格式   第一個行一個數T表示資料組數。後面每組資料,先讀入一個n,接下來兩行每行n個數,每個數的絕對值小於等於1000。   n<=8,T<=1000 輸出格式   一個數表示答案。 樣例輸入 2 3 1 3 -5 -2 4 1 5 1 2 3 4 5 1 0 1 0 1 樣例輸出 -25 6

**注意:**這個是群裡小夥伴的解答。

這裡寫圖片描述

**題目思路:**最主要的邏輯是弄清楚,題目說和最小,其實就是第一行最小乘以第二行最大,第一行次小乘以第二行次大的和,弄清楚了這一點就迎刃而解了,當然為了減輕運算量,我們可以都從小到大排列,然後通過演算法交叉相乘。

題解:

import java.util.Scanner;  

    public class Main {  
        public static void main(String[] args){  
            Scanner in=new Scanner(System.in);  
            int Num=in.nextInt();  
            int i=0,j=0,k=0,c=0;  
            int[] NumArr=new int[Num];  
            for(;c<Num;c++){  
                int m=in.nextInt();//每組資料中有m個元素  
                int[][] a=new int[2][m];  
                for(i=0;i<2;i++){  
                    for(j=0;j<m;j++){  
                        a[i][j]=in.nextInt();  
                    }  
                }  
                int temp=0,sum=0;  
                for(i=0;i<2;i++){  
                    for(j=0;j<m-1;j++){  
                        for(k=j;k<m;k++){  
                            if(a[i][j]>a[i][k]){  
                            temp=a[i][j];  
                            a[i][j]=a[i][k];  
                            a[i][k]=temp;  
                            }  
                        }  
                    }  

                }  
                for(j=0;j<m;j++){  
                    sum+=(a[0][j]*a[1][m-j-1]);  
                }  
                NumArr[c]=sum;  
            }  
            for(c=0;c<Num;c++){System.out.println(NumArr[c]);}  
        }  

    }  

複製程式碼

“演算法每日學計劃”14打卡: 描述 輸入三個字元(可以重複)後,按各字元的ASCII碼從小到大的順序輸出這三個字元。 輸入 第一行輸入一個數N,表示有N組測試資料。後面的N行輸入多組資料,每組輸入資料都是佔一行,有三個字元組成,之間無空格。 輸出 對於每組輸入資料,輸出一行,字元中間用一個空格分開。 樣例輸入 2 qwe asd 樣例輸出 e q w a d s

“演算法每日學計劃”15打卡: 描述 輸入三個字元(可以重複)後,按各字元的ASCII碼從小到大的順序輸出這三個字元。 輸入 第一行輸入一個數N,表示有N組測試資料。後面的N行輸入多組資料,每組輸入資料都是佔一行,有三個字元組成,之間無空格。 輸出 對於每組輸入資料,輸出一行,字元中間用一個空格分開。 樣例輸入 2 qwe asd 樣例輸出 e q w a d s

**注意:**群裡小夥伴解答,感謝!

這裡寫圖片描述

“演算法每日學計劃”16打卡: 時間限制:1.0s 記憶體限制:256.0MB 問題描述 已知一個正整數N,問從1~N中任選出三個數,他們的最小公倍數最大可以為多少。 輸入格式 輸入一個正整數N。 輸出格式 輸出一個整數,表示你找到的最小公倍數。 樣例輸入 9 樣例輸出 504 資料規模與約定 1 <= N <= 106。

**注意:**群裡小夥伴解答,感謝!

解題思路: 思路分析:最大 最小公倍數,聯想到兩個數的求最大最小公倍數,即兩個數的乘積(注:連續的兩個自然數是互斥的)。

同樣,我們可以拿最後三個數來做考慮。

1.當n為奇數時,n,n-1,n-2為奇偶奇,裡面只有一個偶數,所以不會有2這個因子。這三個數相差不到3,所以也不會有因子3,故符合題意。

2.當n為偶數時,n,n-1,n-2為偶奇偶,此時n,n-2肯定含有因子2,所以除於2不值得。所以考慮將n-2 換成n-3,變成奇偶奇,此時也有一個問題,

n和n-3,如果n%3==0,則除於3更不值得。仍根據奇偶奇的原則,變動偶數n為n-2,此時換成n-1,n-2,n-3和1情況一樣。故此時符合題意。

這裡寫圖片描述

“演算法每日學計劃”16打卡: 描述 現在,有一行括號序列,請你檢查這行括號是否配對。 輸入 第一行輸入一個數N(0<N<=100),表示有N組測試資料。後面的N行輸入多組輸入資料,每組輸入資料都是一個字串S(S的長度小於10000,且S不是空串),測試資料組數少於5組。資料保證S中只含有"[","]","(",")"四種字元 輸出 每組輸入資料的輸出佔一行,如果該字串中所含的括號是配對的,則輸出Yes,如果不配對則輸出No 樣例輸入 3 [(]) (]) ([]) 樣例輸出 No No Yes

16

“演算法每日學計劃”17打卡: 時間限制:5000 ms | 記憶體限制:65535 KB 難度:3 描述 給定一整型數列{a1,a2...,an},找出連續非空子串{ax,ax+1,...,ay},使得該子序列的和最大,其中,1<=x<=y<=n。 輸入 第一行是一個整數N(N<=10)表示測試資料的組數) 每組測試資料的第一行是一個整數n表示序列中共有n個整數,隨後的一行裡有n個整數I(-100=<I<=100),表示數列中的所有元素。(0<n<=1000000) 輸出 對於每組測試資料輸出和最大的連續子串的和。 樣例輸入 1 5 1 2 -1 3 -2 樣例輸出 5

**注意:**群裡小夥伴解答,感謝!

這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述

“演算法每日學計劃”18打卡:   問題描述   編寫一個程式,讀入一組整數,這組整數是按照從小到大的順序排列的,它們的個數N也是由使用者輸入的,最多不會超過20。然後程式將對這個陣列進行統計,把出現次數最多的那個陣列元素值列印出來。如果有兩個元素值出現的次數相同,即並列第一,那麼只列印比較小的那個值。   輸入格式:第一行是一個整數N,N £ 20;接下來有N行,每一行表示一個整數,並且按照從小到大的順序排列。   輸出格式:輸出只有一行,即出現次數最多的那個元素值。 輸入輸出樣例 樣例輸入 5 100 150 150 200 250 樣例輸出 150

**注意:**群裡小夥伴解答,感謝!

這裡寫圖片描述

這裡寫圖片描述

“演算法每日學計劃”19打卡: 描述 現在給出你一些數,要求你寫出一個程式,輸出這些整數相鄰最近的素數,並輸出其相距長度。如果左右有等距離長度素數,則輸出左側的值及相應距離。 如果輸入的整數本身就是素數,則輸出該素數本身,距離輸出0 輸入 第一行給出測試資料組數N(0<N<=10000) 接下來的N行每行有一個整數M(0<M<1000000), 輸出 每行輸出兩個整數 A B. 其中A表示離相應測試資料最近的素數,B表示其間的距離。 樣例輸入 3 6 8 10 樣例輸出 5 1 7 1 11 1 注意:打卡啦,打卡啦。

解答:

這裡寫圖片描述

“演算法每日學計劃”20打卡: 描述 在nn方陳裡填入1,2,...,nn,要求填成蛇形。例如n=4時方陳為: 10 11 12 1 9 16 13 2 8 15 14 3 7 6 5 4 輸入 直接輸入方陳的維數,即n的值。(n<=100) 輸出 輸出結果是蛇形方陳。 樣例輸入 3 樣例輸出 7 8 1 6 9 2 5 4 3

**注意:**群裡小夥伴解答,感謝!

這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述

“演算法每日學計劃”21打卡: 描述 給定兩個數m,n,其中m是一個素數。 將n(0<=n<=10000)的階乘分解質因數,求其中有多少個m。 輸入 第一行是一個整數s(0<s<=100),表示測試資料的組數 隨後的s行, 每行有兩個整數n,m。 輸出 輸出m的個數。 樣例輸入 2 100 5 16 2 樣例輸出 24 15

**注意:**群裡小夥伴解答,感謝!

這裡寫圖片描述
這裡寫圖片描述