2018秋招 腾讯笔试

题目一:小Q的歌单

小Q有X首长度为A的不同的歌和Y首长度为B的不同的歌,现在小Q想用这些歌组成一个总长度正好为K的歌单,每首歌最多只能在歌单中出现一次,在不考虑歌单内歌曲的先后顺序的情况下,请问有多少种组成歌单的方法。

输入描述:

每个输入包含一个测试用例。
每个测试用例的第一行包含一个整数,表示歌单的总长度K(1<=K<=1000)。
接下来的一行包含四个正整数,分别表示歌的第一种长度A(A<=10)和数量X(X<=100)以及歌的第二种长度B(B<=10)和数量Y(Y<=100)。保证A不等于B。

输出描述:

输出一个整数,表示组成歌单的方法取模。因为答案可能会很大,输出对1000000007取模的结果。

示例1

输入

5
2 3 3 3

输出

9
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define mst(a, b) memset(a, b, sizeof a)
int main(){
    const int mod=1e9+7;
    long long c[105][105];
    c[0][0]=1;
    for(int i=1;i<=101;i++){
        c[i][0]=1;
        for(int j=1;j<=100;j++){
            c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
        }
    }
    int k,a,x,b,y;
    long long  ans=0;
    cin>>k>>a>>x>>b>>y;
    for(int i =0;i<=x;i++){
        if( k-a*i>=0 && (k-a*i)%b==0 && (k-a*i)/b<=y){
            ans=(ans+(c[x][i]*c[y][(k-a*i)/b])%mod)%mod;
        }
    }
    cout<<ans;
    return 0;
}

题目二:安排机器

小Q的公司最近接到m个任务, 第i个任务需要xi的时间去完成, 难度等级为yi。
小Q拥有n台机器, 每台机器最长工作时间zi, 机器等级wi。
对于一个任务,它只能交由一台机器来完成, 如果安排给它的机器的最长工作时间小于任务需要的时间, 则不能完成,如果完成这个任务将获得200 * xi + 3 * yi收益。

对于一台机器,它一天只能完成一个任务, 如果它的机器等级小于安排给它的任务难度等级, 则不能完成。

小Q想在今天尽可能的去完成任务, 即完成的任务数量最大。如果有多种安排方案,小Q还想找到收益最大的那个方案。小Q需要你来帮助他计算一下。

输入描述:

输入包括N + M + 1行,
输入的第一行为两个正整数n和m(1 <= n, m <= 100000), 表示机器的数量和任务的数量。
接下来n行,每行两个整数zi和wi(0 < zi < 1000, 0 <= wi <= 100), 表示每台机器的最大工作时间和机器等级。
接下来的m行,每行两个整数xi和yi(0 < xi < 1000, 0 <= yi<= 100), 表示每个任务需要的完成时间和任务的难度等级。

 输出描述:

输出两个整数, 分别表示最大能完成的任务数量和获取的收益。

示例1

输入

1 2
100 3
100 2
100 1

输出

1 20006
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
struct node{
    int x,y;
} e[maxn],f[maxn];
int cmp(node a,node b){//从大到小排序
    if(a.x==b.x) return a.y>b.y;
    else return a.x>b.x;
}
char str[55][55];
int main() {
    int n,m,num;
    int cnt[105];
    long long ans=0;
    scanf("%d %d",&n,&m);
    
    for(int i=0;i<n;i++){
       scanf("%d %d",&e[i].x,&e[i].y); 
    }
    for(int i=0;i<m;i++){
       scanf("%d %d",&f[i].x,&f[i].y); 
    }
    sort(e,e+n,cmp);//机器e n
    sort(f,f+m,cmp);//任务 f m
    memset(cnt,0,sizeof(cnt));
    
    for(int i=0,j=0;i<m;i++){
        while(j<n && e[j].x>=f[i].x){
            cnt[e[j].y]++;
            j++;
        }
        for(int k=f[i].y;k<=100;k++){
            if(cnt[k] ){
                num++;
                cnt[k]--;
                ans+=200*f[i].x+3*f[i].y;
                break;
            }
        }
        
    }
    cout<<num<<' '<<ans;
	return 0;
}

题目三:画家小Q

画家小Q又开始他的艺术创作。小Q拿出了一块有NxM像素格的画板, 画板初始状态是空白的,用'X'表示。
小Q有他独特的绘画技巧,每次小Q会选择一条斜线, 如果斜线的方向形如'/',即斜率为1,小Q会选择这条斜线中的一段格子,都涂画为蓝色,用'B'表示;如果对角线的方向形如'\',即斜率为-1,小Q会选择这条斜线中的一段格子,都涂画为黄色,用'Y'表示。
如果一个格子既被蓝色涂画过又被黄色涂画过,那么这个格子就会变成绿色,用'G'表示。
小Q已经有想画出的作品的样子, 请你帮他计算一下他最少需要多少次操作完成这幅画。

输入描述:

每个输入包含一个测试用例。
每个测试用例的第一行包含两个正整数N和M(1 <= N, M <= 50), 表示画板的长宽。
接下来的N行包含N个长度为M的字符串, 其中包含字符'B','Y','G','X',分别表示蓝色,黄色,绿色,空白。整个表示小Q要完成的作品。

输出描述:

输出一个正整数, 表示小Q最少需要多少次操作完成绘画。

示例1

输入

4 4
YXXB
XYGX
XBYY
BXXY

输出

3

说明

XXXX
XXXX
XXXX
XXXX
->
YXXX
XYXX
XXYX
XXXY
->
YXXB
XYBX
XBYX
BXXY
->
YXXB
XYGX
XBYY
BXXY
#include<bits/stdc++.h>
using namespace std;
int n,m;
char str[55][55];
void dfs_Y(int x,int y){
    if(x>=0 &&x<n && y>=0 && y<m && (str[x][y]=='Y'||str[x][y]=='G')){
        if(str[x][y]=='G') str[x][y]='B';
        else str[x][y]='X';
        dfs_Y(x+1,y+1);
    }
}
void dfs_B(int x,int y){
    if(x>=0 &&x<n && y>=0 && y<m && (str[x][y]=='B'||str[x][y]=='G')){
        if(str[x][y]=='G') str[x][y]='Y';
        else str[x][y]='X';
        dfs_B(x+1,y-1);
        
    }
}

int main() {
    int cnt=0;
    scanf("%d %d",&n,&m);
    for(int i=0;i<n;i++){
       scanf("%s",str[i]); 
    }
    
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(str[i][j]=='Y'){
                dfs_Y(i,j);
                cnt++;
            }
            else if(str[i][j]=='B'){
                dfs_B(i,j);
                cnt++;
            }
            else if(str[i][j]=='G'){
                dfs_Y(i,j);
                cnt++;
                dfs_B(i,j);
                cnt++;
            }
        }
    }
    cout<<cnt;
	return 0;
}

题目四:贪吃的小Q

小Q的父母要出差N天,走之前给小Q留下了M块巧克力。小Q决定每天吃的巧克力数量不少于前一天吃的一半,但是他又不想在父母回来之前的某一天没有巧克力吃,请问他第一天最多能吃多少块巧克力

输入描述:

每个输入包含一个测试用例。
每个测试用例的第一行包含两个正整数,表示父母出差的天数N(N<=50000)和巧克力的数量M(N<=M<=100000)。

输出描述:

输出一个数表示小Q第一天最多能吃多少块巧克力。

示例1

输入

3 7

输出

4
#include<iostream>
using namespace std;
int n,m;
//计算第一天吃s个巧克力一共需要多少个多少个巧克力
int sum(int s){
    int sum=0;
    for(int i=0;i<n;i++){
        sum+=s;
        s=(s+1)>>1;//向上取整
    }
    return sum;
}
//二分查找
int fun(){
    if(n==1) return m;
    int low=1;
    int high=m;//第一天的巧克力一定是大于等于1小于等于m的
    while(low<high){
        int mid=(low+high+1)>>1;//向上取整
        if(sum(mid)==m) return mid;//如果第一天吃mid个巧克力,刚刚好吃完所有巧克力,那么直接返回
        else if(sum(mid)<m){
            low=mid;
        }else{
            high=mid-1;
        }
    }
    return high;
}
int main()
{
    cin>>n>>m;
    int res=fun();
    cout<<res<<endl;
    return 0;
}

题目五:纸牌游戏

牛牛和羊羊正在玩一个纸牌游戏。这个游戏一共有n张纸牌, 第i张纸牌上写着数字ai。
牛牛和羊羊轮流抽牌, 牛牛先抽, 每次抽牌他们可以从纸牌堆中任意选择一张抽出, 直到纸牌被抽完。
他们的得分等于他们抽到的纸牌数字总和。
现在假设牛牛和羊羊都采用最优策略, 请你计算出游戏结束后牛牛得分减去羊羊得分等于多少。

输入描述:

输入包括两行。
第一行包括一个正整数n(1 <= n <= 105),表示纸牌的数量。
第二行包括n个正整数ai(1 <= ai <= 109),表示每张纸牌上的数字。

输出描述:

输出一个整数, 表示游戏结束后牛牛得分减去羊羊得分等于多少。

示例1

输入

3
2 7 4

输出

5
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
n=int(input())
line=list(map(int,input().split()))
line.sort(reverse=True)
a=line[::2]
b=line[1::2]
print(sum(a)-sum(b))

 题目六:翻转数列

小Q定义了一种数列称为翻转数列:
给定整数n和m, 满足n能被2m整除。对于一串连续递增整数数列1, 2, 3, 4..., 每隔m个符号翻转一次, 最初符号为'-';。
例如n = 8, m = 2, 数列就是: -1, -2, +3, +4, -5, -6, +7, +8.
而n = 4, m = 1, 数列就是: -1, +2, -3, + 4.
小Q现在希望你能帮他算算前n项和为多少。 

输入描述:

输入包括两个整数n和m(2 <= n <= 109, 1 <= m), 并且满足n能被2m整除。

输出描述:

输出一个整数, 表示前n项和。

输入例子1:

8 2

输出例子1:

8
#include <iostream>
using namespace std;
int main(){
    long n,m;
    cin>>n>>m;
    cout<<n*m/2<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/behboyhiex/article/details/82263186