牛客网--网易2018校招编程题合集

牛客网--网易2018校招编程题合集

 

链接:https://www.nowcoder.com/questionTerminal/32c71b52db52424c89a565e4134bfe4e
来源:牛客网

小易准备去魔法王国采购魔法神器,购买魔法神器需要使用魔法币,但是小易现在一枚魔法币都没有,但是小易有两台魔法机器可以通过投入x(x可以为0)个魔法币产生更多的魔法币。
魔法机器1:如果投入x个魔法币,魔法机器会将其变为2x+1个魔法币
魔法机器2:如果投入x个魔法币,魔法机器会将其变为2x+2个魔法币
小易采购魔法神器总共需要n个魔法币,所以小易只能通过两台魔法机器产生恰好n个魔法币,小易需要你帮他设计一个投入方案使他最后恰好拥有n个魔法币。

输入描述:
输入包括一行,包括一个正整数n(1 ≤ n ≤ 10^9),表示小易需要的魔法币数量。
输出描述:
输出一个字符串,每个字符表示该次小易选取投入的魔法机器。其中只包含字符'1'和'2'。
示例1

输入

10

输出

122

 

逆推。

 

#include <cstdio>
const int MAXN = 100000 + 10;
 
int n, cnt,  num[MAXN];
 
int main(){
    while(scanf("%d", &n) != EOF){
        cnt = 0; 
        while(n){
            if(n%2 == 1){
                num[cnt++] = 1;
                n = (n - 1)/2;
            }else{
                num[cnt++] = 2;
                n = (n - 2)/2;
            }
        }
        for(int i=cnt-1; i>=0; --i){
            printf("%d", num[i] );
        }
        printf("\n");
    }
    return 0;
}

  

链接:https://www.nowcoder.com/questionTerminal/ef6262d0381d42ebbe22d8a8554fef01?source=relative
来源:牛客网

为了得到一个数的"相反数",我们将这个数的数字顺序颠倒,然后再加上原先的数得到"相反数"。例如,为了得到1325的"相反数",首先我们将该数的数字顺序颠倒,我们得到5231,之后再加上原先的数,我们得到5231+1325=6556.如果颠倒之后的数字有前缀零,前缀零将会被忽略。例如n = 100, 颠倒之后是1.

输入描述:
输入包括一个整数n,(1 ≤ n ≤ 10^5)
输出描述:
输出一个整数,表示n的相反数
示例1

输入

1325

输出

6556

直接法。

#include <cstdio>
 
int GetRev(int n){
    int ans = 0;
    while(n){
        ans = 10*ans + n%10;
        n /= 10;
    }
    return ans;
}
 
int main(){  
 
    int ans, n;
    while(scanf("%d", &n) != EOF){
        ans = n + GetRev(n);
        printf("%d\n", ans );
    }
    return 0;
}

  

链接:https://www.nowcoder.com/questionTerminal/97bc02e432bb4744a9e666b6c93d4479?source=relative
来源:牛客网

[编程题]字符串碎片
一个由小写字母组成的字符串可以看成一些同一字母的最大碎片组成的。例如,"aaabbaaac"是由下面碎片组成的:'aaa','bb','c'。牛牛现在给定一个字符串,请你帮助计算这个字符串的所有碎片的平均长度是多少。
输入描述:
输入包括一个字符串s,字符串s的长度length(1 ≤ length ≤ 50),s只含小写字母('a'-'z')
输出描述:
输出一个整数,表示所有碎片的平均长度,四舍五入保留两位小数。

如样例所示: s = "aaabbaaac"
所有碎片的平均长度 = (3 + 2 + 3 + 1) / 4 = 2.25
示例1

输入

aaabbaaac

输出

2.25

 

直接法。

 

#include <cstdio>
#include <cstring>
const int MAXN = 100 + 10;
 
int main(){
 
    int len, i = 0,  cnt = 0, sum = 0;
    char ch[MAXN];
 
    scanf("%s", ch);
    len = strlen(ch);
 
    while(i < len){
        sum += 1; 
        while(i + 1 < len && ch[i] == ch[i+1]){
            ++sum; 
            ++i;
        }
        ++cnt;
        ++i;
    }
    printf("%.2lf\n", (1.0 * sum / cnt) );
    return 0;
}

  

链接:https://www.nowcoder.com/questionTerminal/f58859adc39f4edc9cd8e40ba4160339?source=relative
来源:牛客网

编程题]游历魔法王国
魔法王国一共有n个城市,编号为0~n-1号,n个城市之间的道路连接起来恰好构成一棵树。
小易现在在0号城市,每次行动小易会从当前所在的城市走到与其相邻的一个城市,小易最多能行动L次。
如果小易到达过某个城市就视为小易游历过这个城市了,小易现在要制定好的旅游计划使他能游历最多的城市,请你帮他计算一下他最多能游历过多少个城市(注意0号城市已经游历了,游历过的城市不重复计算)。
输入描述:
输入包括两行,第一行包括两个正整数n(2 ≤ n ≤ 50)和L(1 ≤ L ≤ 100),表示城市个数和小易能行动的次数。
第二行包括n-1个整数parent[i](0 ≤ parent[i] ≤ i), 对于每个合法的i(0 ≤ i ≤ n - 2),在(i+1)号城市和parent[i]间有一条道路连接。
输出描述:
输出一个整数,表示小易最多能游历的城市数量。
示例1

输入

5 2
0 1 2 3

输出

3

树形dp,最经典的树形dp方法。

 

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std; 
 
const int MAXN = 55;
 
struct Node{
    int v;
    Node *next;
};
 
Node ed[2*MAXN], *head[MAXN];
int n, L, cnt, dp[2][MAXN][2*MAXN];
 
void AddEdge(int v, int u){
    ed[cnt].v = v;
    ed[cnt].next = head[u];
    head[u] = &ed[cnt++];
}
 
void dfs(int fa, int cur){
    Node *p;
    dp[1][cur][0] = 1;
    for(int i=1; i<=L; ++i){
        dp[0][cur][i] = dp[1][cur][i] = 1;
    }
    for(p=head[cur]; p!=NULL; p=p->next){
        int v = p->v;
        if(v == fa){
            continue;
        }
        dfs(cur, v);
        for(int i=L; i>=0; --i){
            int j = 0;
            for(; j+2<=i; ++j){
                dp[1][cur][i] = max(dp[1][cur][i], dp[1][cur][j] + dp[1][v][i-j-2]);
                dp[0][cur][i] = max(dp[0][cur][i], dp[1][cur][j] + dp[0][v][i-j-1]);
                dp[0][cur][i] = max(dp[0][cur][i], dp[1][cur][j] + dp[1][v][i-j-1]);
                dp[0][cur][i] = max(dp[0][cur][i], dp[0][cur][j] + dp[1][v][i-j-2]);
            }
            if(j + 1 <= i){
                dp[0][cur][i] = max(dp[0][cur][i], dp[1][cur][j] + dp[0][v][i-j-1]);
                dp[0][cur][i] = max(dp[0][cur][i], dp[1][cur][j] + dp[1][v][i-j-1]);
            }
        }
    }
}
 
int main(){
 
    int ans, tmp;
    while(scanf("%d %d", &n, &L) != EOF){
        memset(dp, 0, sizeof(dp));
        memset(head, 0, sizeof(head));
        cnt = 0;
        for(int i=1; i<n; ++i){
            scanf("%d", &tmp);
            AddEdge(tmp, i);
            AddEdge(i, tmp);
        }
        dfs(0, 0);
        ans = max(dp[0][0][L], dp[1][0][L]);
        printf("%d\n", ans );
    }
    return 0;
}

  

链接:https://www.nowcoder.com/questionTerminal/a461395335c946c5b409e79847796cd0
来源:牛客网

[编程题]重排数列
小易有一个长度为N的正整数数列A = {A[1], A[2], A[3]..., A[N]}。
牛博士给小易出了一个难题:
对数列A进行重新排列,使数列A满足所有的A[i] * A[i + 1](1 ≤ i ≤ N - 1)都是4的倍数。
小易现在需要判断一个数列是否可以重排之后满足牛博士的要求。
输入描述:
输入的第一行为数列的个数t(1 ≤ t ≤ 10),
接下来每两行描述一个数列A,第一行为数列长度n(1 ≤ n ≤ 10^5)
第二行为n个正整数A[i](1 ≤ A[i] ≤ 10^9)
输出描述:
对于每个数列输出一行表示是否可以满足牛博士要求,如果可以输出Yes,否则输出No。
示例1

输入

2
3
1 10 100
4
1 2 3 4

输出

Yes
No

 

直接法,计算 可以被4整除的数的个数, 和不被2整除的个数,%4 个数  >= %2 mod 1 个数即可。

 

#include <cstdio>
#include <cstring>
const int MAXN = 100 + 10;
 
int main(){
 
    int n, t, c4, c1, TC;
    scanf("%d", &TC);
    while(TC--){
        scanf("%d", &n);
        c1 = 0; c4 = 0;
        for(int i =0; i<n; ++i){
            scanf("%d", &t);
            if(t % 4 == 0){
                ++c4;
            }else if(t % 2 == 1){
                ++c1;
            }
        }
        if( c4 >= c1 ){
            printf("Yes\n");
        }else{
            printf("No\n");
        }
    }
    return 0;
}

  

链接:https://www.nowcoder.com/questionTerminal/504ad6420b314e5bb614e1684ad46d4d?source=relative
来源:牛客网

[编程题]最长公共子括号序列
一个合法的括号匹配序列被定义为:
1. 空串""是合法的括号序列
2. 如果"X"和"Y"是合法的序列,那么"XY"也是一个合法的括号序列
3. 如果"X"是一个合法的序列,那么"(X)"也是一个合法的括号序列
4. 每个合法的括号序列都可以由上面的规则生成
例如"", "()", "()()()", "(()())", "(((()))"都是合法的。
从一个字符串S中移除零个或者多个字符得到的序列称为S的子序列。
例如"abcde"的子序列有"abe","","abcde"等。
定义LCS(S,T)为字符串S和字符串T最长公共子序列的长度,即一个最长的序列W既是S的子序列也是T的子序列的长度。
小易给出一个合法的括号匹配序列s,小易希望你能找出具有以下特征的括号序列t:
1、t跟s不同,但是长度相同
2、t也是一个合法的括号匹配序列
3、LCS(s, t)是满足上述两个条件的t中最大的
因为这样的t可能存在多个,小易需要你计算出满足条件的t有多少个。

如样例所示: s = "(())()",跟字符串s长度相同的合法括号匹配序列有:
"()(())", "((()))", "()()()", "(()())",其中LCS( "(())()", "()(())" )为4,其他三个都为5,所以输出3.
输入描述:
输入包括字符串s(4 ≤ |s| ≤ 50,|s|表示字符串长度),保证s是一个合法的括号匹配序列。
输出描述:
输出一个正整数,满足条件的t的个数。
示例1

输入

(())()

输出

3

 

转了一个弯,其实就是判断 len-1的LCS的s,这个s可以由插入一个字符串得到。(加上判断合法性即可)

 

#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;
 
 
bool isLegal(string s){
    int l = 0, r = 0;
    for(int i=0; i<s.length(); ++i){
        if(s[i] == '('){
            ++l;
        }else{
            ++r;
        }
        if(r > l){
            return false;
        }
    }
    return true;
}
 
 
int main(){
 
    string s;
    cin >> s;
 
    int len = s.length();
 
    unordered_map<string, int> mp;
    mp[ s ] = 1;
 
    int ans = 0;
 
    for(int i=0; i<len; ++i){
        string t1 = s.substr(0, i) + s.substr(i+1);
        for(int j=0; j<len; ++j){
            if(i == j){
                continue;
            }
            string tmp = t1.substr(0, j) + s[i] + t1.substr(j);
            // cout << tmp << endl; 
            if(isLegal(tmp) && mp.find(tmp) == mp.end()){
                mp[ tmp ] = 1;
                ++ans;
            }
        }
    }
    cout << ans << endl; 
    return 0;
}

  

 

转载于:https://www.cnblogs.com/zhang-yd/p/7509289.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值