【美团点评】2020校招系统开发方向笔试题

还是只写了编程题。这套题写了大概一个半小时。。下午刚做完的。

还是有点难。。QAQ我不会字符串是真的/


 

 

试题链接:2020校招系统开发方向笔试题

 

7、 大数加法

题意:以字符串的形式读入两个数字,再以字符串的形式输出两个数字的和。

 

题解:这题我做过!!!之前用java参加蓝桥杯的时候学过23333(应该是说自从那次去参加湖北今日头条杯,场上压8位精度c++板子被草之后回来就去学了java大数。。。)

java的大整数类的应用,详情可以看链接,里面有很多java的常见用法。

这题的坑点是,它的引号是当作字符输入的。。!QAQ所以要去除引号。

 

代码:

 1 import java.util.Scanner;
 2 import java.math.BigInteger;
 3  
 4 public class Main{
 5     public static void main(String[] args) {
 6         Scanner scanner = new Scanner(System.in);
 7         String num1 = scanner.nextLine();
 8         String num2 = scanner.nextLine();
 9         num1 = num1.substring(1,num1.length()-1);
10         num2 = num2.substring(1,num2.length()-1);
11         //初始化
12         BigInteger n1 = new BigInteger(num1);
13         BigInteger n2 = new BigInteger(num2);
14          
15         //System.out.println(n1);
16         //System.out.println(n2);
17         BigInteger sum = n1.add(n2);        //
18  
19         System.out.println("\""+sum+"\"");
20     }
21  
22 }
View Code

 

 

8、 回文子串

题意:给定一个字符串,你的任务是计算这个字符串中有多少个回文子串(回文串是一个正读和反读都一样的字符串)。

具有不同开始位置或结束位置的回文串,即使是由相同的字符组成,也会被计为是不同的子串。

 

题解:这个题就是最长回文子串的变形,我们做一个统计就可以,最长回文子串可以看链接。

 

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1010;
 4 int dp[maxn][maxn] = {0};
 5  
 6 int main(){
 7     string s;
 8     cin>>s;
 9     int len = s.size();
10     int cnt = 0;
11     cnt += len;
12     for(int i = 0; i < len ;i++){
13         dp[i][i] = 1;
14         if(s[i] == s[i+1]){
15             dp[i][i+1] = 1;
16             cnt++;
17         }
18     }
19     for(int pos = 3; pos<=len ; pos++){
20         for(int i = 0 ;i <= len-pos; i++){
21             int j = i+pos-1;
22             if(dp[i+1][j-1] && s[i] == s[j]){
23                 dp[i][j]=1;
24                 cnt++;
25             }
26         }
27     }
28  
29     cout<<cnt<<endl;
30      
31     return 0;
32 }
View Code

 

 

9、合并金币

题意:有 N 堆金币排成一排,第 i 堆中有 C[i] 块金币。每次合并都会将相邻的两堆金币合并为一堆,成本为这两堆金币块数之和。经过N-1次合并,最终将所有金币合并为一堆。请找出将金币合并为一堆的最低成本。

其中,1 <= N <= 30,1 <= C[i] <= 100

 

题解:以前打比赛训练的时候有做过一道叫做合并石子的题。一道经典的区间dp应用。

其实之前最先做这个题我是用贪心,但是明显贪心不对。因为这是选择相邻的两堆金币。

我们用dp[l][r]表示l到r区间合并的最小值。接下来就是划分子问题。

我们将[l,r]区间做一个k的划分,以k为分界点,可以划分成[l,k]和[k+1,r](所以k不能枚举到r啦)

这样就能得到状态转移方程 dp[l][r] = min(dp[l][r],dp[l][k] + dp[k+1][r] + cost[l][r])

这里的花费就是合并金币所需要的花费。从[l,r]的花费也就是金币总个数(做初始化即可)/

(补了一下注释,虽然也没啥)这种题目还有很多变种类型,优化也有很多。

 

代码:

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 105;
 4 
 5 int n;
 6 int num[maxn]={0};
 7 int dp[maxn][maxn]={0};
 8 int cost[maxn][maxn]={0};
 9 
10 int main(){
11     cin>>n;
12     for(int i = 1;i <= n;i++)   cin>>num[i];
13 
14     memset(dp,0x3f,sizeof(dp));
15     
16     //花费初始化
17     for(int i = 1; i <= n;i++){
18         for(int j = i; j <= n ;j++){
19             for(int k = i; k <= j; k++){
20                 cost[i][j] += num[k];
21             }
22         }
23     }
24     
25     for(int i = 1; i <= n ;i++)    dp[i][i] = 0;
26 
27     //枚举k  [l,r]->[l,k]+[k+1,r]
28     for(int len = 2; len <= n;len++){
29         for(int l = 1; l <= n-len+1 ;l++){
30             int r = l+len-1;
31             for(int k = l ; k < r; k++){
32                 dp[l][r] = min(dp[l][r],dp[l][k] + dp[k+1][r]+cost[l][r]);
33             }
34         }
35     }
36 
37     cout<<dp[1][n]<<endl;
38     return 0;
39 }
View Code

 

 

 

 

10、最小唯一前缀

题意:给定一组个字符串,为每个字符串找出能够唯一识别该字符串的最小前缀。

 

题解:当时脑子里想到是字典树,但是不信邪,要去做暴力。。但是暴力的不够优美。。

于是上了板子3分钟就AC了。/trie树真的很好用。。准备多做字符串的题了。。我字符串真的好弱。

 

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3  
 4 const int maxn = 105;
 5 const int maxnode = 100005;
 6  
 7 string str[maxn];
 8  
 9 int ch[maxn][maxn];
10 char val[maxn];
11  
12 struct Trie {
13     int sz;
14     Trie() {
15         sz = 1;
16         memset(ch[0], 0, sizeof(ch[0]));
17     }
18     int idx(char c) { return c - 'a'; }
19  
20     void insert(string s) {
21         int u = 0;
22         int n = s.size();
23         for(int i = 0; i < n; i++) {
24             int c = idx(s[i]);
25             if(!ch[u][c]) {
26                 memset(ch[sz], 0, sizeof(ch[sz]));
27                 val[sz] = 0;
28                 ch[u][c] = sz++;
29             }
30             u = ch[u][c];
31             val[u]++;
32         }
33     }
34  
35     void query(string s) {
36         int u = 0;
37         int n = s.size();
38         for(int i = 0; i < n; i++) {
39             putchar(s[i]);
40             int c = idx(s[i]);
41             if(val[ch[u][c]] == 1) return ;
42             u = ch[u][c];
43         }
44     }
45 };
46  
47 int main() {
48     Trie trie;
49     int n;
50     cin>>n;
51     for(int i = 0;i < n ;i++){
52         cin>>str[i];
53         trie.insert(str[i]);
54     }
55     for(int i = 0; i < n; i++) {
56         trie.query(str[i]);
57         cout<<endl;
58     }
59     return 0;
60 }
View Code

 

posted @ 2020-03-19 18:46  甜酒果。  阅读(1015)  评论(1编辑  收藏  举报