今日頭條2017後端工程師實習生筆試題

 第一題:編程

傳送門數組

[編程題]最大映射

有 n 個字符串,每一個字符串都是由 A-J 的大寫字符構成。如今你將每一個字符映射爲一個 0-9 的數字,不一樣字符映射爲不一樣的數字。這樣每一個字符串就能夠看作一個整數,惟一的要求是這些整數必須是正整數且它們的字符串不能有前導零。如今問你怎樣映射字符才能使得這些字符串表示的整數之和最大?測試


輸入描述:

每組測試用例僅包含一組數據,每組數據第一行爲一個正整數 n , 接下來有 n 行,每行一個長度不超過 12 且僅包含大寫字母 A-J 的字符串。 n 不大於 50,且至少存在一個字符不是任何字符串的首字母。spa



輸出描述:

輸出一個數,表示最大和是多少。.net


輸入例子:
2
ABC
BCA

輸出例子:
1875

 

題解轉自:code

http://blog.csdn.net/yang20141109/article/details/51284495blog

 

解析:給大寫字母A~J中的每個字母賦一個權重,按照權重由大到小進行排序,依次把9~0十個數字賦值給排序好的的字母。問題的關鍵就在於咱們如何給字母賦值權重。假如咱們有字符串"ABCD",咱們從低位到高位依次給每一個字母賦值爲1,10,100,1000...等。w(D) = 1,w(C) = 10,w(B) = 100,w(A) = 1000。最後咱們把輸入字符串中的每一個字符的權重相加。好比字符串"ABC"和字符串"BCA"。賦值及求和以下圖所示:

    由於字符串映射爲的整數不存在前導零,因此咱們須要作一步特殊的處理,在每一個字符串首位置出現的字符都不能爲零。若是出現這種狀況,咱們須要把不在首部出現的具備最小權值字符提到排好序的數組的首部。

 

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<algorithm>
 5  
 6 using namespace std;
 7  
 8 #define N 55
 9 #define M 30
10 #define ll long long
11  
12 char s[N][M];
13 int flag[M];
14 int le[N];
15 int n;
16 ll ma;
17 
18 struct PP{
19     ll quan;
20     ll ch;
21 }X[N],te;
22 
23 bool cmp(PP a,PP b){
24     return a.quan < b.quan;
25 }
26  
27 void ini(){
28     int i,j;
29     memset(flag,0,sizeof(flag));
30     memset(X,0,sizeof(X));
31     ma = 0;
32     for(i = 0;i < n;i++){
33         scanf("%s",s[i]);
34         le[i] = strlen(s[i]);
35     }
36     ll temp = 1;
37     for(i = 0;i < n;i++){
38         flag[ s[i][0] - 'A' ] = -1;
39         temp = 1;
40         for(j = le[i] - 1;j >= 0;j--){
41             X[ s[i][j] - 'A' ].quan += temp;
42             X[ s[i][j] - 'A' ].ch = s[i][j] - 'A';
43             temp *= 10;
44         }
45     }
46 }
47 
48 void solve(){
49     sort(X,X + 10,cmp);
50     int i;
51     int pos;
52     if(X[0].quan != 0){
53         for(i = 0;i < 10;i++){
54             if(flag[ X[i].ch ] == -1){
55                 continue;
56             }
57             else{
58                 pos = i;
59                 te = X[i];
60                 break;
61             }
62         }
63         for(i = pos - 1;i >= 0;i--){
64             X[i+1] = X[i];
65         }
66         X[0] = te;
67     } 
68     for(i = 0;i < 10;i++){
69         ma += i * X[i].quan;
70     }
71     
72 }
73  
74 int main(){
75     while(scanf("%d",&n) != EOF){
76         ini();
77         solve();
78         printf("%lld\n",ma);
79     }
80 }

 

 

第二題:排序

[編程題] 木棒拼圖

有一個由不少木棒構成的集合,每一個木棒有對應的長度,請問可否用集合中的這些木棒以某個順序首尾相連構成一個面積大於 0 的簡單多邊形且全部木棒都要用上,簡單多邊形即不會自交的多邊形。字符串

初始集合是空的,有兩種操做,要麼給集合添加一個長度爲 L 的木棒,要麼刪去集合中已經有的某個木棒。每次操做結束後你都須要告知是否能用集合中的這些木棒構成一個簡單多邊形。get


輸入描述:

每組測試用例僅包含一組數據,每組數據第一行爲一個正整數 n 表示操做的數量(1 ≤ n ≤ 50000) , 接下來有n行,每行第一個整數爲操做類型 i (i ∈ {1,2}),第二個整數爲一個長度 L(1 ≤ L ≤ 1,000,000,000)。若是 i=1 表明在集合內插入一個長度爲 L 的木棒,若是 i=2 表明刪去在集合內的一根長度爲 L 的木棒。輸入數據保證刪除時集合中一定存在長度爲 L 的木棒,且任意操做後集合都是非空的。



輸出描述:

對於每一次操做結束有一次輸出,若是集合內的木棒能夠構成簡單多邊形,輸出 "Yes" ,不然輸出 "No"。


輸入例子:
5
1 1
1 1
1 1
2 1
1 2

輸出例子:
No
No
Yes
No
No

 

注意:

multiset<ll>s;

 

用multiset刪除某個數要用:

s.erase(s.find(y));

 

s.erase(y);

會把相同的數一塊兒刪除

 

 

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<set>
 6 
 7 using namespace std;
 8 
 9 #define N 50005
10 #define ll long long
11 
12 ll sum;
13 ll ma;
14 int n;
15 int sz;
16 
17 int main(){
18     while(scanf("%d",&n) != EOF){
19         ma = 0;
20         sum = 0;
21         multiset<ll>s;
22         multiset<ll>::iterator it;
23         int i;
24         int x;
25         ll y;
26         for(i = 0;i < n;i++){
27             scanf("%d%lld",&x,&y);
28             if(x == 1){
29                 s.insert(y);
30                 sum += y;
31             }
32             else{
33                 s.erase(s.find(y));
34                 sum -= y;
35             }
36             it = s.end();
37             it --;
38             ma = *it;
39             sz = s.size();
40             if(sz >= 3 && (sum - ma) > ma ){
41                 printf("Yes\n");
42             }
43             else{
44                 printf("No\n");
45             }
46         }
47     }
48     
49 }
相關文章
相關標籤/搜索