美团点评秋招编程题
来源:互联网 发布:晴天软件注册码 编辑:程序博客网 时间:2024/04/28 15:55
[编程题] 大富翁游戏
时间限制:1秒
空间限制:32768K
大富翁游戏,玩家根据骰子的点数决定走的步数,即骰子点数为1时可以走一步,点数为2时可以走两步,点数为n时可以走n步。求玩家走到第n步(n<=骰子最大点数且是方法的唯一入参)时,总共有多少种投骰子的方法。
输入描述:
输入包括一个整数n,(1 ≤ n ≤ 6)
输出描述:
输出一个整数,表示投骰子的方法
输入例子1:
6
输出例子1:
32
解析:
f(n)表示走到n的方案数量。每次走的步数为[1-6]。
第一次可以走1步,则剩下n-1未走, 方案数为f(n-1);
第一次也可以走2步,则剩下n-2未走,方案数为f(n-2);
…
第一次走6步,则剩下n-6未走,方案数为f(n-6);
因此,走到n的方案有:
f(n) = f(n-1)+f(n-2)+f(n-3)+f(n-4)+f(n-5)+f(n-6)。
其中,f(0)=1,f(1)=1
c++代码实现:
#include <iostream>using namespace std;int main(){ int n; cin>>n; int fn[7]={1,1,0,0,0,0,0}; for(int i=2; i<=n; i++){ for(int j=1; j<=i; j++){ fn[i] += fn[i-j]; } } cout<<fn[n]; return 0;}
[编程题] 拼凑钱币
时间限制:1秒
空间限制:32768K
给你六种面额 1、5、10、20、50、100 元的纸币,假设每种币值的数量都足够多,编写程序求组成N元(N为0~10000的非负整数)的不同组合的个数。
输入描述:
输入包括一个整数n(1 ≤ n ≤ 10000)
输出描述:
输出一个整数,表示不同的组合方案数
输入例子1:
1
输出例子1:
1
解析:
类似于背包问题,只是每种纸币可以选取多个。即对于每个面额为coin[i]纸币,选X[i]个,使得sum(coin[i]*x[i]) = n元。
我们可以假设每种面额的纸币只选一次,从1元纸币开始,则总共只需要选择6次,每次选择对应的面额的纸币。
用dp[i][j]代表选择i次凑成j元的不同组合个数,结果即为dp[6][n]。
dp[0][j] = 0, 选择0次不可能凑成j元;
dp[i][0] = 1, 选择i次凑成0元的方案只有一个,那就是每种面额纸币的数量都为0。
对于dp[i][j],举个例子dp[3][10]表示选择i次凑成10元的方案数,第三次可以选择0或1张10元的纸币,这意味着前2次选择后,已经凑成了10元或者0元。
即dp[3][10]=dp[2][10]+dp[2][0]。
因此,对于dp[i][j],第i次选可以选择0~j/coin[i]张面额为coin[i]的纸币,即前i-1次选择后,已经有了j-k*coin[i]的钱。
dp[i][j] = sum(dp[i-1][j-k*coin[i]]), k = 0~j/coin[i]
C++代码实现:
#include <iostream>using namespace std;long long dp[7][10001]={0};int coin[6] = {1,5,10,20,50,100};long long combineN(int n){ int i,j,k,m; for( i=0; i<=n; i++) dp[0][i] = 0; for( i=0; i<=6; i++) dp[i][0] = 1; //凑0元的方案就只有一种,那就是都不选 for(int i=1; i<=6; i++){ for( j=1; j<=n; j++){ m = j/coin[i-1]; for( k=0; k<=m; k++) dp[i][j] += dp[i-1][j-k*coin[i-1]]; } } return dp[6][n];}int main(){ int n; cin>>n; cout<<combineN(n); return 0;}
[编程题] 最大矩形面积
时间限制:1秒
空间限制:32768K
给定一组非负整数组成的数组h,代表一组柱状图的高度,其中每个柱子的宽度都为1。 在这组柱状图中找到能组成的最大矩形的面积(如图所示)。 入参h为一个整型数组,代表每个柱子的高度,返回面积的值。
输入描述:
输入包括两行,第一行包含一个整数n(1 ≤ n ≤ 10000)
第二行包括n个整数,表示h数组中的每个值,h_i(1 ≤ h_i ≤ 1,000,000)
输出描述:
输出一个整数,表示最大的矩阵面积。
输入例子1:
6
2 1 5 6 2 3
输出例子1:
10
解析:
(1)方法一:穷举法。对于每个柱子,穷举所有的左边界,记录最大面积。这样穷举时间复杂度为O(n^2)。因此,必须剪枝,比如找到合适的右边界。我们发现当height[k] >= height[k-1]时,无论左边界取什么值,选择height[k]作为右边界总会比选择height[k-1]所形成的面积大。因此,在选择右边界时,我们首先找到一个height[k] < height[k-1]的k, 然后取k-1作为右边界, 然后穷举所有的左边界,找到最大面积。
(2)方法二:穷举法还有一个思路。对于每个柱子i,定义left[i]和right[i],分别表示柱子i能延伸的左边界,和柱子i能延伸的右边界,然后计算该矩形的面积。柱子i的左边界为离i最近的j,且height[j] < height[i],左边界即为j+1。柱子的右边界为离i最近的j,且height[j] < height[i],右边界即为j-1。时间复杂度为O(n)。
(3)方法三:使用一个栈的O(n)解法,栈内存储的是高度递增的柱子下标。对于每一个柱子i,分两种情况: 1:当栈空或者当前柱子i高度大于栈顶下标所指示柱子的高度时,当前下标入栈。否则,2:当前栈顶出栈,并且用这个下标所指示的柱子高度计算面积。而这个方法为什么只需要一个栈呢?因为当第二种情况时,for循环的循环下标回退,也就让下一次for循环比较当前柱子高度与新的栈顶下标所指示的柱子高度,注意此时的栈顶已经改变。
C++代码实现:
方法一
#include <iostream>#include <queue>using namespace std;int n;int height[10000];long long maxArea(){ long long result = 0,area = 0; for(int i=0; i<n; i++){ for(int k=i+1; k<n; k++){ if(height[k-1] > height[k]){ i = k - 1; //右边界 break; } else i = k; } int lowest = height[i]; for(int j=i; j>=0; j--){ lowest = lowest<height[j]?lowest:height[j]; area = lowest*(i-j+1); if(area>result) result = area; } } return result;}int main(){ cin>>n; for(int i=0; i<n; i++) cin>>height[i]; cout<<maxArea(); return 0;}
方法二
#include <iostream>#include <queue>using namespace std;int n=1;int height[10000];long long maxArea(){ long long result = 0,area = 0; int left[n], right[n]; int i=0,j=0; //查找每根柱子的左边界 left[0] = 0; for( i=1; i<n; i++){ j = i; while(j>=1 && height[j-1]>=height[i]) j--; left[i] = j; } //查找每根柱子的右边界 right[n-1] = n-1; for(int i=n-2; i>=0; i--){ j = i; while(j<n-1 && height[j+1]>=height[i]) j++; right[i] = j; } for(int i=0; i<n; i++){ area = (right[i]-left[i]+1)*height[i]; if(area>result) result = area; } return result;}int main(){ cin>>n; for(int i=0; i<n; i++) cin>>height[i]; cout<<maxArea(); return 0;}
方法三:
#include <iostream>#include <stack>using namespace std;int n=1;int height[10000];long long maxArea(){ long long result = 0,area = 0; int start = 0; stack<int> rectangle; for(int i=0; i<n; i++){ if(rectangle.empty() || height[rectangle.top()] < height[i]) rectangle.push(i); else{ start = rectangle.top(); rectangle.pop(); if(rectangle.empty()) area = height[start]*i; else area = height[start]*(i-rectangle.top()-1); if(area>result) result = area; i--; } } while(!rectangle.empty()){ start = rectangle.top(); rectangle.pop(); if(rectangle.empty()) area = height[start]*n; else area = height[start]*(n-rectangle.top()-1); if(area>result) result = area; } return result;}int main(){ cin>>n; for(int i=0; i<n; i++) cin>>height[i]; cout<<maxArea(); return 0;}
[编程题] 最长公共连续子串
时间限制:1秒
空间限制:32768K
给出两个字符串(可能包含空格),找出其中最长的公共连续子串,输出其长度。
输入描述:
输入为两行字符串(可能包含空格),长度均小于等于50.
输出描述:
输出为一个整数,表示最长公共连续子串的长度。
输入例子1:
abcde
abgde
输出例子1:
2
解析:
动态规划。dp[i][j]表示子串Xi和Yj的最长连续公共子串的长度。
如果x[i]==y[j],则dp[i+1][j+1] = dp[i][j] + 1
其中最大的dp[i][j],即为X和Y的最长连续公共子串。
C++代码实现
#include <iostream>using namespace std;string x,y;int dp[51][51] = {0};int maxLength(){ int lenX = x.size(); int lenY = y.size(); int result = 0; for(int i=0; i<lenX; i++) dp[i][0] = 0; for(int j=0; j<lenY; j++) dp[0][j] = 0; for(int i=0; i<lenX; i++){ for(int j=0; j<lenY; j++){ if(x[i]==y[j]) dp[i+1][j+1] = dp[i][j]+1; if(dp[i+1][j+1]>result) result = dp[i+1][j+1]; } } return result;}int main(){ getline(cin,x); getline(cin,y); cout<<maxLength(); return 0;}
- 美团点评秋招编程题
- 美团点评2017秋招笔试编程题
- 美团点评2017秋招笔试编程
- 2017美团点评秋招笔试编程
- 美团点评 2017春招编程题
- 美团点评2017秋招笔试真题A
- 美团点评校招笔试题
- 美团点评编程题
- 美团2017秋招编程题
- 美团点评2017秋招笔试真题-运维工程师B
- 美团点评2017秋招笔试真题-运维工程师A
- 美团点评2017秋招笔试真题-算法工程师A 部分详解
- 《美团点评编程题》整数加法
- 美团点评编程笔试题
- 美团点评2018笔试编程题
- 2018美团点评编程题第一题
- 美团点评2017校园招聘编程题--取红包
- 美团点评CodeM编程大赛-题一
- CentOS上tomcat启动巨慢问题
- jquery tmpl模板
- X Chen笔记---百度云破解限速
- MySQL连接符
- display:none与visible:hidden的区别
- 美团点评秋招编程题
- charles的一些用法整理
- <12> ——Integer to Roman
- ardupilot & px4 书写自己的app & drivers (一)
- 【八月英语总结】- baby在成长
- 当 git pull 碰到拒绝合并无关历史
- 20.日期类型
- Centos7安装32位库用来安装32位软件程序
- GUI程序设计原理