搜狗筆試題——密碼生成


問題:

小汪作為一個有數學天分的程序猿,設計了一套密碼生成器來搞定自己的密碼問題。
密碼生成器由N個槽位組成,槽位的下標為0~N-1,每個槽位存儲一個數。起初每個槽位都是0。
密碼生成器會進行M輪計算,每輪計算,小汪會輸入兩個數L,R(L<=R),密碼生成器會將這兩個數作為下標,將兩個下標之間(包含)的所有槽位賦值為i(i為當前的輪次,i∈[1,M])。
M輪計算完成后,密碼生成器會根據槽位的最終值生成一條密碼,密碼的生成規則為:
(0*a[0] + 1*a[1] + 2*a[2] + ... + (N-1)*a[N-1]) mod 100000009
其中a[i]表示第i個槽位的最終值。
請幫助小汪把他的密碼生成器實現為代碼。

鏈接:https://www.nowcoder.com/questionTerminal/96bf0c548a094de7a05919e0b32b1a5a?toCommentId=6455114
來源:牛客網

分析

  (1)第一種方式,根據題意使用數組表示槽位。但是最壞的時間復雜度達到O(m*n),我的代碼只能通過30%的測試。  (2)第二種方式,使用問題轉換。只記錄分割片段,輸入數據的同時實時更新已經記錄的片段。最后通過數學公式獲得最終值。我的代碼在本地能通過題目提供的測試,但是在web端提交運行出現錯誤且未通過(您的代碼已保存

請檢查是否存在數組越界等非法訪問情況)。在這種方法中,槽位n並沒有被實際用到。

代碼

方式1代碼:

 1 import java.util.Arrays;
 2 import java.util.Scanner;
 3 
 4 /**
 5  *題目:小汪的密碼問題
 6  * 使用數組記錄每個槽位
 7  */
 8 public class Main6_1{
 9     public static void main(String args[]){
10         Scanner in = new Scanner(System.in);
11         int n,m;
12         n = in.nextInt();   //槽位
13         m = in.nextInt();   //運算輪次
14         int[] dp = new int[n];  //創建槽位
15         int x,y;
16         //循環計算
17         for(int i=1;i<=m;i++){
18             x = in.nextInt();
19             y = in.nextInt();
20             /*while(x<=y){
21                 dp[x++]=i;
22                 dp[y--]=i;
23             }*/
24             //內部實際也是遍歷填充
25             Arrays.fill(dp,x,y+1,i);
26             //System.out.println(Arrays.toString(dp)); //顯示每一輪計算后的結果
27         }
28         //根據規則計算結果值
29         double res = 0;
30         for(int i=0;i<n;i++){
31             res+=i*dp[i];
32         }
33         //對結果值取模
34         System.out.printf("%.0f",res%100000009);
35     }
36 }
View Code

 

方式2代碼:

 1 import java.util.*;
 2 
 3 /**
 4  *題目:小汪的密碼問題
 5  * 使用map記錄片段
 6  * 動態分割片段:使用新片段分割老片段
 7  *
 8  * 存在四種情況
 9  * 設已經存在的片段端點為a1,b1,新片段端點為a2,b2
10  * case1:a1<a2<=b1
11  * 分割結果:(a1,a2-1),(a2,b2)
12  * case2:a2<=a1 && b2>=b1
13  * 分割結果:(a2,b2)
14  * case3:a1<=b2<b1
15  * 分割結果:(b2+1,b1),(a2,b2)
16  * case4:a1<a2 && b2 > b1
17  * 分割結果:(a1,a2-1) (a2,b2),(b2+1,b1)
18  *
19  * 運行結果提示:請檢查是否存在數組越界等非法訪問情況
20  * 猜測:在外部對map進行了修改。測序出現錯誤
21  */
22 public class Main6_2{
23     public static void main(String args[]){
24         Scanner in = new Scanner(System.in);
25         int m,n;
26         n = in.nextInt();
27         m = in.nextInt();
28         //記錄每次輪次的所有片段,因為前面的片段可能被后面的輪次進行更細小的切割
29         Map<Integer,Map<Integer,Integer>> dp = new HashMap<>();
30         int a2,b2;
31         //循環輪次
32         for(int i=1;i<=m;i++){
33             a2 = in.nextInt();
34             b2 = in.nextInt();
35 
36             //更新已經存在的片段:覆蓋、再分割
37             for(int j=1;j<i;j++){
38                 //如果存在該輪dp.get(i)!=null && dp.get(i).size()>0次的片段,實施分割
39                 if(dp.get(j)!=null && dp.get(j).size()>0){
40                     Map<Integer,Integer> curMap = dp.get(j);
41                     for(Map.Entry<Integer,Integer> entry:curMap.entrySet()){
42                             int a1 = entry.getKey();
43                             int b1 = entry.getValue();
44                         if(a2>a1 && a2<=b1){  //case1:a1<a2<=b1
45                             entry.setValue(a2-1);
46                         }else if(a2<=a1 && b2>=b1){  //case2:a2<=a1 && b2>=b1
47                            curMap.remove(a1);
48                         }else if(b2>=a1 && b2<b1){ //case3:a1<=b2<b1
49                             curMap.remove(a1);
50                             curMap.put(b2+1,b1);
51                         }else if(a1<a2 && b2>b1){     //case4:a1<a2 && b2 > b1
52                             entry.setValue(a2-1);
53                             curMap.put(b2+1,b1);
54                         }
55                     }
56                 }
57             }
58             //放入當前片段
59             Map<Integer,Integer> tmp = new HashMap<>();
60             tmp.put(a2,b2);
61             dp.put(i,tmp);
62 
63         }
64         double res = 0;
65         /*
66         單個片段的計算公式:
67         (1)片段長度為count
68         (2)片段輪次為i
69         (3)片段首位坐標為為x,y
70         (4)計算公式整合:x*i+(x+1)*i .... +y*i = (x+(x+1)+...+y)*i
71          */
72         for(int i=1;i<=m;i++){
73             if(dp.get(i)!=null && dp.get(i).size()>0){
74                 Map<Integer,Integer> curMap = dp.get(i);
75                 for(Map.Entry<Integer,Integer> entry:curMap.entrySet()){
76                     int x = entry.getKey();
77                     int y = entry.getValue();
78                     int count = y-x+1;
79                     double v = (count*(x+y))/2.0;
80                     res+=i*v;
81                 }
82             }
83         }
84         System.out.printf("%.0f",res%100000009);
85     }
86 }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM