2019.9.1 拼多多 服务端研发-笔试(C++)

拼多多的笔试没有选择题,直接是四道编程题,非常干脆直接,上手就是干!

优先偶数的有序TopN

题目描述:

读入一个数列和N值,返回按优先级排序的N个数,满足:
(1)所有偶数优先级大于奇数
(2)同为偶数或同为奇数时,数值大的优先级高

输入描述:

每个测试输入的测试用例,包含一个用半角逗号(,)分开的自然数数列和1一个参数N,数列和参数N用半角分号(;)隔开
这里保证N小于数列的元素个数(不超过100)

输入:(示例)

555503,772867,756893,339138,399447,40662,859037,628085,855723,974471,599631,636153,581541,174761,948135,411485,554033,858627,402833,546467,574367,360461,566480,755523,222921,164287,420256,40043,977167,543295,944841,917125,331763,188173,353275,175757,950417,284578,617621,546561,913416,258741,260569,630583,252845;10

输出:

// 略。。。


题解:
分别对奇数和偶数排序,然后再按序输出前面N个数即可
(这里我采用了vector分别存储两个数,然后对他们用sort排序,在for循环输出前面N个数)

AC代码:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

bool isNum(int a)
{
	if(a%2==0) return true;
	else return false;
} // return true 则为偶数

bool cmp(int a,int b)
{
	return a>b;
}

int main()
{
	// freopen("C:\\Users\\24398\\Desktop\\in-project.txt", "r", stdin);
    int n,num;
    vector<int> v1,v2;

    while(cin>>num)   // 输入数据
    {
    	if(isNum(num))
    	{
    		v1.push_back(num);
    	}else
    	{
    		v2.push_back(num);
    	}
        
        char c;
        cin>>c;
        if(c==';')
        {
        	break;
        }
    }
    cin>>n;

    sort(v1.begin(),v1.end(),cmp);  //排序
    sort(v2.begin(),v2.end(),cmp);

    for (int i = 0; i < n-1; ++i)     //打印输出
    {   
    	if(i<v1.size())
    	   cout<<v1[i]<<",";
    	else
    	   cout<<v2[(i-1-v1.size())]<<",";
    }

    if(n>v1.size())
    {
       cout<<v2[n-1-v1.size()]<<endl;
    }else
    {
       cout<<v1[n-1]<<endl;
    }

    return 0;
}

扑克游戏

■题目描述

产品经理小梅喜欢和他的男朋友小白一块玩扑克游戏。每一局,小梅抽取N张扑克牌,自左向右依次排列在桌面上;小白也抽取M (8>=N>=M>=1)张扑克牌,自左向右依次排列在桌面上。
小梅需要进行N个回合,使用手中的扑克牌,组成一个新的扑克牌的序列。每个回合,小梅有d、|、 r三种策略:-选择d时,小梅将最左边的扑克牌丢弃
一选择1时,小梅将最左边的扑克牌取出,放到新的扑克牌序列的最左边
-选择r时,小梅将最左边的扑克牌取出,放到新的扑克牌序列的最右边
N个回合完成,新的扑克牌序列与小白的扑克牌完全一-样 (只考虑数字,不考虑花色),则小梅胜出。
小梅向程序员小岛提了一个需求,希望了解获胜的全部方法。简化起见,扑克牌仅包含1-9。

输入描述:

首先,输入数字S,作为局数(1<=S<=10)。
每一局,分别输入两行字符串,分别代表小梅的抽取的扑克牌(从左向右排列)和小白抽取到的扑克牌(从左向右排列)

输出描述:

对于每一局,在开始和结束,分别输出{和}。
输出获胜的方法,回合策略的结尾输出一个空格。若存在多个获胜方法,请按字典序的

输入:(示例)

3
123
3
123
321
45
67

输出:

{
d d l
d d r
}
{
l l l
r l l
}
{
}


题解:
用回溯法列出所有结果,然后匹配结果,看是否符合,若满足条件则输出res

AC代码

#include <iostream>
#include <algorithm>
#include <string>

using namespace std;

void outRes(const string& str)
{
	int length=str.size();
	if(length<=1)
	{
		cout<<str[length];
		return;
	}
	for (int i = 0; i < length-1; ++i)
	{
		cout<<str[i]<<" ";
	}
	cout<<str[length-1]<<endl;
}

void dfs(int n,int s,string res,string str1,string str2,string tmp)
{
     if(n==s)
     {
     	if(tmp==str2)
     		outRes(res);
     	return;     	
     }

     string left = string(1,str1[0]);
     str1 = str1.substr(1,str1.size()-1);

     dfs(n+1,s,res+"d",str1,str2,tmp);
     dfs(n+1,s,res+"r",str1,str2,tmp+left);
     dfs(n+1,s,res+"l",str1,str2,left+tmp);
}


int main()
{
	//	freopen("C:\\Users\\24398\\Desktop\\in-project.txt", "r", stdin);
		
    int s; cin>>s;
    string strN,strM;

    while(s>0)
    {
    	s--;
        cin>>strN>>strM;
        
        const int s=strN.size();

        cout<<"{"<<endl;
        dfs(0,s,"",strN,strM,"");
        cout<<"}"<<endl;
    }

	return 0;
}

骰子期望

题目描述:

给定n个骰子,进行投掷,接下来给出n个骰子可能出现的情况数,出现每一种情况的概率相同,比如给出3,那么就可能出现1,2,3三种情况,每种的概率相同;求输出的最大值的期望值

输入描述:

第一行给出骰子数:n
第二行:n个骰子可能出现的情况数

输出描述:

输出期望值

示例:

输入:

2
2 2

输出:

1.75

// 这题借鉴了别人的代码,不能确定是否ac

#include <iostream>
#include <vector>

using namespace std;
 
int main(){
    int n,tmp;
    int m_max=0;
    vector<int> cnt;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>tmp;
        m_max = (m_max<tmp)?tmp:m_max;
        cnt.push_back(tmp);
    }
     
    vector<double> p(n);
    double q1=0.0,q2=0.0,res=0.0;
    for(int k=1;k<=m_max;k++){
        q1=1.0;
        for(int i=0;i<n;i++){
            p[i]=(cnt[i]>=k)?((1.0*k)/cnt[i]):1.0;
            q1 *= p[i];
        }
        res += (q1-q2)*k;
        q2=q1;
    }
    printf("%.2f",res);
     
    return 0;
}


二维表第k大数

题目描述:

几乎每一个人都用 乘法表。但是你能在乘法表中快速找到第k小的数字吗?
给定高度m 、宽度n 的一张 m * n的乘法表,以及正整数k,你需要返回表中第k 小的数字。

示例 1:

输入: m = 3, n = 3, k = 5
输出: 3
解释:
乘法表:
1 2 3
2 4 6
3 6 9

第5小的数字是 3 (1, 2, 2, 3, 3).

例 2:

输入: m = 2, n = 3, k = 6
输出: 6
解释:
乘法表:
1 2 3
2 4 6

第6小的数字是 6 (1, 2, 2, 3, 4, 6).

注意:
m 和 n 的范围在 [1, 30000] 之间。
k 的范围在 [1, m * n] 之间。

注意:如果用数组暴力求解,内存一定会超,只能a到百分之30

AC代码

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int min_(int m,int n,int num)
{
    int count = 0;
    for (int i = 1; i < m; ++i)
    {
        count+=min(num/i,n);
    }
    return count;
}

int TwoSort(int m,int n,int k)
{
     int l=1,r=m*n,mid; //int 最大值,最小值,中间值
     while(l<r)
     {
         mid=(l+r) >> 1;
         int tmp=min_(m,n,mid);
         if(tmp<k)
         {
            l=mid+1;
         }else
         {
            r=mid+1;
         }
     }
     return l;
}

int main()
{
    int n,m,k; cin>>n>>m>>k;

    if(k==1) cout<<1<<endl;
    if(k==m*n) cout<<n*m<<endl;

    cout<<TwoSort(m,n,k)<<endl;

	return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值