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

119 篇文章 0 订阅

题目名称:
大数加法
题目描述:
以字符串的形式读入两个数字,再以字符串的形式输出两个数字的和。
输入描述:
输入两行,表示两个数字a和b,-109 <= a , b <= 109 ,用双引号括起。
输出描述:
输出a+b的值,用双引号括起。
输入:
“-26”
“100”
输出:
“74”
题意:
题目描述
题解
直接搞
代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
 
typedef long long ll;
const int maxn = 10000 + 5;
char s1[maxn],s2[maxn];
 
int main(){
    while(scanf("%s%s",s1,s2)!=EOF){
        bool flag1 = false;
        bool flag2 = false;
        int l1 = strlen(s1);
        int l2 = strlen(s2);
        ll sum1 = 0;
        ll sum2 = 0;
        for(int i = 0; i < l1; i ++){
            if(s1[i] >= '0' && s1[i] <= '9'){
                int t = s1[i] - '0';
                sum1 = sum1 * (ll)10 + (ll)t;
            }
            else if(s1[i] == '-') flag1 = true;
        }
        for(int i = 0; i < l2; i ++){
            if(s2[i] >= '0' && s2[i] <= '9'){
                int t = s2[i] - '0';
                sum2 = sum2 * (ll)10 + (ll)t;
            }
            else if(s2[i] == '-') flag2 = true;
        }
        char c ='\"';
        if(flag1) sum1 = -sum1;
        if(flag2) sum2 = -sum2;
        printf("%c%d",c,(sum1 + sum2),c);
        printf("%c\n",c);
    }
    return 0;
}

题目名称:
回文子串
题目描述:
给定一个字符串,你的任务是计算这个字符串中有多少个回文子串(回文串是一个正读和反读都一样的字符串)。
具有不同开始位置或结束位置的回文串,即使是由相同的字符组成,也会被计为是不同的子串。
输入描述:
输入仅包含一个字符串,长度不会超过 1000。
输出描述:
输出仅包含一个非负整数, 代表输入字符串有多少个回文子串。
输入:
abc
aaa
输出:
3
6
题意:
题目描述
题解
数据范围也不大,直接暴力枚举
代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
 
const int maxn = 1000 + 5;
char s[maxn];
 
bool judge(int st,int ed){
    while(st <= ed){
        if(s[st] != s[ed]) return false;
        st ++;
        ed --;
    }
    return true;
}
 
int main(){
    while(scanf("%s",s)!=EOF){
        int l = strlen(s);
        int ans = 0;
        for(int i = 0; i < l; i ++){
            for(int j = i; j < l; j ++){
                bool flag = judge(i,j);
                if(flag) ans ++;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

题目名称:
合并金币
题目描述:
有 N 堆金币排成一排,第 i 堆中有 C[i] 块金币。每次合并都会将相邻的两堆金币合并为一堆,成本为这两堆金币块数之和。经过N-1次合并,最终将所有金币合并为一堆。请找出将金币合并为一堆的最低成本。
其中,1 <= N <= 30,1 <= C[i] <= 100
输入描述:
第一行输入一个数字 N 表示有 N 堆金币
第二行输入 N 个数字表示每堆金币的数量 C[i]
输出描述:
输出一个数字 S 表示最小的合并成一堆的成本
输入:
4
3 2 4 1
30
10 20 30 40 50 60 70 80 90 100 99 89 79 69 59 49 39 29 19 9 2 12 22 32 42 52 62 72 82 92
输出:
20
7037
题意:
题目描述
题解
dp[i][j]表示第i到第j堆石子合并的最优值,sum[i][j]表示第i到第j堆石子的总数量。
len = 1时,i = 1时, j = i+ len = 2。 此时sum[i][j]为i到j的和,k = 1时,就sum[1][2] = sum[1][1] + sum[2][2],同时算出子结构dp[1][2]。这样下次还可以用这个dp[1][2] 作为已知变量,求出 后面的 dp[i][j] 。
代码:

#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
 
const int maxn = 1000 + 5;
int a[maxn],sum[maxn][maxn],dp[maxn][maxn];
 
int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        memset(sum,0,sizeof(sum));
        for(int i = 0; i <= n; i ++){
            for(int j = 0; j <= n; j ++){
                dp[i][j] = 1000000;
            }
        }
        for(int i = 1; i <= n; i ++) scanf("%d",&a[i]);
        for(int i = 1; i <= n; i ++){
            sum[i][i] = a[i];
            dp[i][i] = 0;
        }
        for(int len = 1; len < n; len ++){  //枚举长度
            for(int i = 1; i + len <= n; i ++){ //起点
                int j = i + len; //终点
                for(int k = i; k <= j; k ++){
                    sum[i][j] = sum[i][k] + sum[k + 1][j];
                    dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j] + sum[i][j]);
                }
            }
        }
        printf("%d\n",dp[1][n]);
    }
    return 0;
}

题目名称:
最小唯一前缀
题目描述:
给定一组个字符串,为每个字符串找出能够唯一识别该字符串的最小前缀。
输入描述:
第一行输入一个整数 n 表示字符串个数
后面n行,每行一个字符串,一共n串互不相同的字符串。(2 <= n <= 100,字符串长度不超过100)
输出描述:
输出n行,每行一个字符串,依次是每个字符串的最小可唯一识别前缀
输入:
5
meituanapp
meituanwaimai
dianpingliren
dianpingjiehun
mt
输出:
meituana
meituanw
dianpingl
dianpingj
mt
题意:
题目描述
题解
trie树模板题,暴力也可过
代码:

#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
 
const int maxn = 105;
const int maxnode = 100005;
 
string str[maxn];
 
int ch[maxn][maxn];
char val[maxn];
 
struct Trie {
    int sz;
    Trie() {
        sz = 1;
        memset(ch[0], 0, sizeof(ch[0]));
    }
    int idx(char c) { return c - 'a'; }
 
    void insert(string s) {
        int u = 0;
        int n = s.size();
        for(int i = 0; i < n; i++) {
            int c = idx(s[i]);
            if(!ch[u][c]) {
                memset(ch[sz], 0, sizeof(ch[sz]));
                val[sz] = 0;
                ch[u][c] = sz++;
            }
            u = ch[u][c];
            val[u]++;
        }
    }
 
    void query(string s) {
        int u = 0;
        int n = s.size();
        for(int i = 0; i < n; i++) {
            putchar(s[i]);
            int c = idx(s[i]);
            if(val[ch[u][c]] == 1) return ;
            u = ch[u][c];
        }
    }
};
 
int main() {
    Trie trie;
    int n;
    while(scanf("%d",&n)!=EOF){
        for(int i = 0;i < n ;i++){
            cin>>str[i];
            trie.insert(str[i]);
        }
        for(int i = 0; i < n; i++) {
            trie.query(str[i]);
            cout<<endl;
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值