1. 程式人生 > >2017 今日頭條編程題匯總:

2017 今日頭條編程題匯總:

好的 ^c class through all orm ray state 取值

頭條的2017校招開始了!為了這次校招,我們組織了一個規模宏大的出題團隊,每個出題人都出了一些有趣的題目,而我們現在想把這些題目組合成若幹場考試出來,在選題之前,我們對題目進行了盲審,並定出了每道題的難度系統。一場考試包含3道開放性題目,假設他們的難度從小到大分別為a,b,c,我們希望這3道題能滿足下列條件:
a<=b<=c
b-a<=10
c-b<=10
所有出題人一共出了n道開放性題目。現在我們想把這n道題分布到若幹場考試中(1場或多場,每道題都必須使用且只能用一次),然而由於上述條件的限制,可能有一些考試沒法湊夠3道題,因此出題人就需要多出一些適當難度的題目來讓每場考試都達到要求,然而我們出題已經出得很累了,你能計算出我們最少還需要再出幾道題嗎?
輸入描述:
輸入的第一行包含一個整數n,表示目前已經出好的題目數量。

第二行給出每道題目的難度系數d1,d2,…,dn。

數據範圍
對於30%的數據,1 ≤ n,di ≤ 5;
對於100%的數據,1 ≤ n ≤ 10^5,1 ≤ di ≤ 100。
在樣例中,一種可行的方案是添加2個難度分別為20和50的題目,這樣可以組合成兩場考試:(20 20 23)和(35,40,50)。
輸出描述:
輸出只包括一行,即所求的答案。

輸入例子1:
4
20 35 23 40

輸出例子1:
2

解析: 思路 第一步:進行排序將輸入的難度進行排序處理

    第二步: 首先看 a1,a2,a3 ---這三個數進行比較,確定 添加的題目數

FIRST: 如果 a2-a1<=10 && a3-a2<=10 符合要求,從a4,a5,a6下三組進行開始

SECOND:如果 a2-a1>10 && a2-a1<=20 數量+1,跳到第三個從 a3,a4,a5開始

THIRD:如果a2-a1>20 則所在數量+2,從a2,a3,a4 開始

FORTH:如果a2-a1<=10 ,並且 a3-a2>10 則數量+1,a3,a4,a5 下一組開始

 1 import java.util.Arrays;
 2 import java.util.Scanner;
 3 
 4 /**
 5  * Created by Workstation on 2017/8/21.
 6  */
 7 public class Main {
8 9 public static void main (String[] args) { 10 test_1 (); 11 12 } 13 14 public static void test_1() 15 { 16 Scanner in=new Scanner (System.in); 17 18 int M=in.nextInt (); 19 int[] arr=new int[M]; 20 for(int i=0;i<M;i++) 21 { 22 arr[i]=in.nextInt ();// 依次將輸入的結果進行排序 23 } 24 Arrays.sort (arr); 25 26 //進行處理 27 int count=0,index=0; 28 int n=arr.length; 29 while(index<arr.length) 30 { 31 if((index+1<n) && (index+2)<n && arr[index+1]-arr[index]<=10) 32 { 33 if(arr[index+2]-arr[index+1]<=10)// 屬於第一種情形 34 { 35 index+=3; 36 }else // a3-a2>10 37 { 38 count+=1; 39 index+=2;// 從 a2,a3,a4開始 40 } 41 }else if(index+1<n && arr[index+1]-arr[index]<=20) 42 { 43 count+=1; 44 index+=2; 45 }else 46 { 47 count+=2; 48 index+=1; 49 } 50 } 51 if(index==n-1) count+=2; 52 System.out.println(count); 53 } 54 }

給定整數m以及n各數字A1,A2,..An,將數列A中所有元素兩兩異或,共能得到n(n-1)/2個結果,請求出這些結果中大於m的有多少個。

輸入描述:
第一行包含兩個整數n,m. 
第二行給出n個整數A1,A2,...,An。
數據範圍
對於30%的數據,1 <= n, m <= 1000
對於100%的數據,1 <= n, m, Ai <= 10^5



輸出描述:
輸出僅包括一行,即所求的答案
示例1

輸入

3 10  
6 5 10

解析:

引入 概念T:Trie樹,單詞樹,主要用於 字符串的查找和前綴匹配,
利用串構建一個字典樹,該字典樹保留串的公共的前綴西歐愛心,以英文字母為例子: 每一個Trie樹 中每一個節點包含26個孩子節點,:
技術分享

如下給出字符串"abc","ab","bd","dda",根據該字符串序列構建一棵Trie樹。則構建的樹如下:Trie樹根節點不包含任何信息,第一個字符串"abc" 第一個

字母a,因此在根節點數組中找到字符串下標a-97 數組下標的值不為NULL就行,同樣依次類推:查找字符串“abc“ 查找的長度olog(Len) ,采用匹配耗時間哦(n*len)

解題:使用Tire樹,將n個數字分別裝換成二進制形式進行存儲到Trie樹,比較a[i]元素和m對應二進制每一位的比值:
數據最多10^5 對於每一個節點 使用1<< 17 才能夠滿足哦,因此需要空間10^5*17 byte= 大概是210KB左右的空間;
有用的東西:和1異或相當於該位上的數進行取反,同時a^b=c有 a^c=b:

這一道題:可以擺每一個數的二進制求出來,用一個字典樹進行維護,之後遍歷每一個數按照位的貪心算法進行:
1.如果這一位對應位m是1,那麽與此位相異或必須是1,如果這一位m是0,要大於m的話異或的這一位可以是1或者是0,ans加上之前維護過的二進制位加上這一位為1的數在字典樹中查詢到有多小滿足這個前綴的條件,之後讓這一位的異或為0,繼續往下遍歷,最後除以2
圖如下所示 當前m=0:想大於m這一位相與必須要是1,m=1 只能遞歸判斷下一位
技術分享 直接計算肯定是超時的,所以這問題不能使用暴力破解,考慮到從高位到地位,依次進行位運算,如果兩個數異或結果在某高位為1,而m的對應位為0,則肯定任何這兩位異或結果為1的都會比m大。 直接從高到低位進行判斷 由此,考慮使用字典樹(TrieTree)從高位到第位建立字典,再使用每個元素依次去字典中查對應高位異或為1, 而m為0的數的個數,相加在除以2既是最終的結果;直接貼出代碼如下,非原創,歡迎討論; 補充:queryTrieTree在搜索的過程中,是從高位往低位搜索,那麽,如果有一個數與字典中的數異或結果的第k位大於m的第k位,那麽該數與對應分支中所有的數異或結果都會大於m, 否則,就要搜索在第k位異或相等的情況下,更低位的異或結果。queryTrieTree中四個分支的作用分別如下: 當mDigi位為1 的時候不得不遞歸d下一位 1. aDigit=1, mDigit=1時,字典中第k位為0,異或結果為1,需要繼續搜索更低位,第k位為1,異或結果為0,小於mDigit,不用理會; 2. aDigit=0, mDigit=1時,字典中第k位為1,異或結果為1,需要繼續搜索更低位,第k位為0,異或結果為0,小於mDigit,不用理會; 3. aDigit=1, mDigit=0時,字典中第k位為0,異或結果為1,與對應分支所有數異或,結果都會大於m,第k位為1,異或結果為0,遞歸獲得結果; 4. aDigit=0, mDigit=0時,字典中第k位為1,異或結果為1,與對應分支所有數異或,結果都會大於m,第k位為0,異或結果為0,遞歸獲得結果;
 1 import java.util.Scanner;
 2  
 3 public class Main {
 4     private static class TrieTree {
 5         TrieTree[] next = new TrieTree[2];
 6         int count = 1;
 7     }
 8  
 9     public static void main(String[] args) {
10         Scanner sc = new Scanner(System.in);
11         while (sc.hasNext()){
12             int n = sc.nextInt();
13             int m = sc.nextInt();
14             int[] a = new int[n];
15             for (int i = 0; i < n; i++) {
16                 a[i] = sc.nextInt();
17             }
18             System.out.println(solve(a, m));
19         }
20     }
21  
22     private static long solve(int[] a, int m) {
23         TrieTree trieTree = buildTrieTree(a);
24         long result = 0;
25         for (int i = 0; i < a.length; i++) {
26             result += queryTrieTree(trieTree, a[i], m, 31);
27         }
28         return result / 2;
29     }
30  
31     private static long queryTrieTree(TrieTree trieTree, int a, int m, int index) {
32         if(trieTree == null)
33             return 0;
34  
35         TrieTree current = trieTree;
36         for (int i = index; i >= 0; i--) {
37             int aDigit = (a >> i) & 1;
38             int mDigit = (m >> i) & 1;
39             if(aDigit == 1 && mDigit == 1) {
40                 if(current.next[0] == null)
41                     return 0;
42                 current = current.next[0];
43             } else if (aDigit == 0 && mDigit == 1) {
44                 if(current.next[1] == null)
45                     return 0;
46                 current = current.next[1];
47             } else if (aDigit == 1 && mDigit == 0) {
48                 long p = queryTrieTree(current.next[1], a, m, i - 1);
49                 long q = current.next[0] == null ? 0 : current.next[0].count;
50                 return p + q;
51             } else if (aDigit == 0 && mDigit == 0) {
52                 long p = queryTrieTree(current.next[0], a, m, i - 1);
53                 long q = current.next[1] == null ? 0 : current.next[1].count;
54                 return p + q;
55             }
56         }
57         return 0;
58     }
59  
60     private static TrieTree buildTrieTree(int[] a) {
61         TrieTree trieTree = new TrieTree();
62         for (int i = 0; i < a.length; i++) {
63             TrieTree current = trieTree;
64             for (int j = 31; j >= 0; j--) {
65                 int digit = (a[i] >> j) & 1;
66                 if(current.next[digit] == null) {
67                     current.next[digit] = new TrieTree();
68                 } else {
69                     current.next[digit].count ++;
70                 }
71                 current = current.next[digit];
72             }
73         }
74         return trieTree;
75     }
76 }

輸入 1-n的數字按照字典進行排序

給定整數n和m, 將1到n的這n個整數按字典序排列之後, 求其中的第m個數。
對於n=11, m=4, 按字典序排列依次為1, 10, 11, 2, 3, 4, 5, 6, 7, 8, 9, 因此第4個數是2.
對於n=200, m=25, 按字典序排列依次為1 10 100 101 102 103 104 105 106 107 108 109 11 110 111 112 113 114 115 116 117 118 119 12 120 121 122 123 124 125 126 127 128 129 13 130 131 132 133 134 135 136 137 138 139 14 140 141 142 143 144 145 146 147 148 149 15 150 151 152 153 154 155 156 157 158 159 16 160 161 162 163 164 165 166 167 168 169 17 170 171 172 173 174 175 176 177 178 179 18 180 181 182 183 184 185 186 187 188 189 19 190 191 192 193 194 195 196 197 198 199 2 20 200 21 22 23 24 25 26 27 28 29 3 30 31 32 33 34 35 36 37 38 39 4 40 41 42 43 44 45 46 47 48 49 5 50 51 52 53 54 55 56 57 58 59 6 60 61 62 63 64 65 66 67 68 69 7 70 71 72 73 74 75 76 77 78 79 8 80 81 82 83 84 85 86 87 88 89 9 90 91 92 93 94 95 96 97 98 99 因此第25個數是120…

 1 public class Main {
 2   // 使用一點小手段計算結果只有80% 的通過,說明這個算法還是可以進行調整
 3     public static void main (String[] args) {
 4 
 5        Scanner in=new Scanner (System.in);
 6         Long n=in.nextLong ();
 7         Long m=in.nextLong ();
 8         int cur=1;
 9         for(int i=1;i<m;i++)
10         {
11             if(cur*10<=n)
12             {
13                 cur*=10;// 進行擴展位
14             }else
15             {
16                 if(cur>=n) cur=cur/10;//防止越界
17                 cur+=1;
18                 while(cur%10==0) cur/=10;
19             }
20         }
21         System.out.println(cur);
22     }
23     
24 }

找出函數的最寬尖峰

【題目描述】按數組的形式給出函數f(x)的取值,即數組A的A[0]元素為f(0)的取值,數組的取值都為整數,函數在每個點都是嚴格單調遞增或者嚴格遞減(即A[i-1] != A[i] != A[i+1]),要求找出最寬的先上升後下降的區間(這個區間內函數的值必須先上升到一個點然後下降,區間的上升段和下降段長度必須都大於0)。

1. 如果找到符合條件的最大區間輸出數組對應的左右下標(保證只有一個最大區間)

2. 找不到那麽輸出-1 -1

輸入格式

n

n長度的整數數組

輸出格式

區間的範圍

輸入樣例

10

1 3 1 2 5 4 3 1 9 10

輸出樣例

2 7

數據規模

對於 100% 的數據,1 <=n <=10, 000, 000

解析:此題有點類似與排隊序列相似

 1 public static void test_4()
 2     {
 3         Scanner in=new Scanner(System.in);
 4         int n=in.nextInt ();
 5         int [] x=new int[n];
 6 
 7         for(int i=0;i<n;i++)
 8             x[i]=in.nextInt ();
 9 
10         int [] dpL=new int[n];
11 
12         for(int i=1;i<n;i++)
13         {
14             if(x[i]-x[i-1]>0)
15             {
16                 dpL[i]=dpL[i-1]+1;
17             }
18         }
19 
20         int [] dpR=new int[n];
21 
22         for(int i=n-2;i>=0;i--)
23         {
24             if(x[i]-x[i+1]>0)
25             {
26                 dpR[i]=dpR[i+1]+1;
27             }
28         }
29 
30         int mx=0,LL=-1,RR=-1;
31         for(int i=0;i<n;i++)
32         {
33             if(dpL[i]>0 && dpR[i]>0 && dpL[i]+dpR[i]>mx)
34             {
35                 mx=dpL[i]+dpR[i];
36                 LL=i-dpL[i];
37                 RR=i+dpR[i];
38             }
39         }
40         System.out.println(LL+" "+RR);
41     }

Paragraph

【問題描述】給定一個段落,由 N 個句子組成。第 i 個句子的長度為 L[i],包含的單詞個數為 W[i]。

句子不包含任何除字母和空格( ) 外的符號。

每個句子內部,含有若幹個單詞,由空格( ) 分隔。句子不會包含連續的空格。

隨後給定 M 個查詢,每個查詢包含一個句子,需要在段落中尋找相同單詞數量最多的句子。重復的單詞只計一次,且不區分大小寫。

輸入數據將保證結果是存在且唯一的。

輸入格式

第一行是兩個整數 N 和 M。

接下來的 N+M 行,每行包含一個句子。

前 N 行代表段落中的句子,後 M 行表示查詢。

輸出格式

輸出 M 行,每行代表查詢的結果。

輸入樣例

6 3

An algorithm is an effective method that can be expressed within a finite amount of space and time

Starting from an initial state and initial input the instructions describe a computation

That when executed proceeds through a finite number of successive states

Eventually producing output and terminating at a final ending state

The transition from one state to the next is not necessarily deterministic

Some algorithms known as randomized algorithms incorporate random input

Next to the transition

Wormhole, infinite time and space

The transition from one state to the next is not necessarily deterministic

輸出樣例

The transition from one state to the next is not necessarily deterministic

An algorithm is an effective method that can be expressed within a finite amount of space and time

The transition from one state to the next is not necessarily deterministic

數據規模

0 < L[i] < 512

0 < W[i] < 32

對於 30% 的數據,0 < N < 30,0 < M < 30。

對於 100% 的數據,0 < N < 500,0 < M < 800。



 1 package com.mmall.common.program;
 2 
 3 import java.util.ArrayList;
 4 import java.util.HashSet;
 5 import java.util.List;
 6 import java.util.Scanner;
 7 
 8 /**
 9  * Created by Workstation on 2017/8/23.
10  *
11  * 字符串的處理問題: 從給定的句子和一段語句,從給定句子中查找到段落中相同的語句
12  */
13 public class jiri_4 {
14     public static void main (String[] args) {
15         Scanner sc=new Scanner (System.in);
16 
17         int n=sc.nextInt ();
18         int m=sc.nextInt();
19 
20         // 向下輸入zifuchuan
21         sc.nextLine ();
22 
23         String[] senetences=new String[n];
24         for(int i=0;i<n;i++)
25         {
26             senetences[i]=sc.nextLine ();
27         }
28 
29         List<HashSet<String>> sentenceList=new ArrayList<> ();
30         for(int i=0;i<n;i++)
31         {
32             HashSet<String> set=new HashSet<> ();
33             String[] temp=senetences[i].toLowerCase ().split (" ");
34             for(String s:temp)
35             {
36                 set.add(s);
37             }
38             sentenceList.add(set);
39         }
40 
41         for(int i=0;i<m;i++)
42         {
43             HashSet<String> set = new HashSet<>();
44             String[] temp = sc.nextLine().toLowerCase().split(" ");
45             for (String s : temp) {
46                 set.add(s);
47             }
48             // 遍歷List 找到最大相同的單詞
49             int max=0,maxIndex=0;
50 
51             for(int j=0;j<n;j++)
52             {
53                 HashSet<String> targetSentence=sentenceList.get(j);
54                 int count=0;
55                 for(String s:set)
56                 {
57                     if(targetSentence.contains (s))
58                     {
59                         count++;
60                     }
61                 }
62                 if(count>max)
63                 {
64                     max=count;
65                     maxIndex=j;
66                 }
67                 System.out.println(senetences[maxIndex]);
68             }
69         }
70     }
71 }




2017 今日頭條編程題匯總: