别家的笔试总是做的很差,偏偏做华为的就有状态。。。
首先得感谢牛客的@当可乐遇上曼妥思贴出来的题目
1.
给你N行M列的人,他们是一个方阵。左上角是(0,0),右下角是(n-1, m-1),最外圈的人顺时针报数,当他们报的数个位是7并且十位是奇数,就选出来。外圈报完了内圈接着报,一直到所有人都报完,问最后选出来的是哪些。
要求是10<=n,m<=1000,如果输入不合法,那么就是返回空数组。
好像很多人卡在空数组的输出上了。
输入
10 10
输出
[[7,9],[1,1],[8,2],[7,5],[4,4]]
#include <iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<string>
using namespace std;
bool isvalid(int count) {
if (count % 10 == 7 && (count / 10) % 2 == 1)
return true;
else return false;
}
int main() {
int m, n;
cin >> m >> n;
if (m <10 || n < 10 || n>1000 || m>1000) {
cout << "[]";
return 0;
}
vector<vector<int>> res;
int up = 0, down = m - 1, left = 0, right = n - 1;
int count = 0;
while (up <= down && left <= right) {
for (int i = left; i <= right; i++) {
count++;
if (isvalid(count))
res.push_back({ up,i });
}
up++;
for (int i = up; i <= down; i++) {
count++;
if (isvalid(count))
res.push_back({ i,right });
}
right--;
for (int i = right; i >= left; i--) {
count++;
if (isvalid(count))
res.push_back({ down,i });
}
down--;
for (int i = down; i >= up; i--) {
count++;
if (isvalid(count))
res.push_back({ i,left });
}
left++;
}
cout << '[';
for (int i = 0; i<res.size(); i++) {
if (i == res.size() - 1)
cout << '[' << res[i][0] << ',' << res[i][1] << ']';
else cout << '[' << res[i][0] << ',' << res[i][1] << ']' << ',';
}
cout << ']';
return 0;
}
2.
给你N个节点,然后输入他们所在的高度,问最后的二叉树可以有几种,结果可能很大,对10^9+7 取模
输入
4 1 0 2 2
输出
2
例子
x
/
x
/
x x
或者
x
x
/
x x
写的很简陋,没全A,其实就是排列组合题,抽空看下通用写法,溢出太烦人了
#include <iostream>
#include<vector>
#include<algorithm>
#include<map>
using namespace std;//排列组合问题
int cmn(long long m, long long n) {
if (m == n)
return 1;
if (m - n<n) n = m - n;
long long res = 1;
while (m>0) {
res *= m--;
}
while (n>0) {
res /= n--;
}
return (int)(res % 1000000007);
}
int main() {
int n;
cin >> n;
vector<int> nums(n, 0);
map<int,int> statis;
int temp;
for (int i = 0; i<n; i++) {
cin >> temp;
nums[i] = temp;
statis[temp]++;
}
sort(nums.begin(), nums.end());
if (statis.rbegin()->first > statis.size()-1) {
cout << 0 << endl;
return 0;
}
int res = 1;
auto preitr = statis.begin();
if (preitr->second > 1 || preitr->second == 0) {
cout << 0;
return 0;
}
for (auto itr = statis.begin(); itr != statis.end(); itr++) {
if (itr == statis.begin())
continue;
if (itr->second > 2 * preitr->second) {
cout << 0;
return 0;
}
res = (res*cmn(pow(2, preitr->second), itr->second)) % 100000007;
preitr = itr;
}
cout << res;
return 0;
}
3.
现在有一个已经落下来了一些的俄罗斯方块,我们用一个字符串表示,分别代表每个位置上已经落了多少块了。比如2202,就是下图
现在,有一个新的俄罗斯方块要掉下来,它的描述也是类似的,
例如121,就是下图
掉下来的块,一定保证是上底对齐的,并且不会出现下图这种情况
然后众所周知,落下来以后,如果一行没有间断的话,那么这一行就能消掉了,上面的那些就会往下落。
掉下来的块不能旋转,可以左右平移,但不能超出边界,让你最后没有被消除的行数尽可能小,问你这个值是多大。
输入
2202
2
输出
0
如果你不把2放在原本的0处的话,那么现在的未消行数就是4
#include <iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<string>
using namespace std;
int main() {
string frame;
cin >> frame;
string brick;
cin >> brick;
int n = frame.size(), m = brick.size();
int len = n - m + 1;
int res=99999;
for (int i = 0; i<len; i++) {
int minval = 99999, maxval = -99999;
string cframe = frame;
int l = 0;
for (int j = i; j<i + m; j++) {
cframe[j] += (brick[l++] - '0');
}
for (int k = 0; k<n; k++) {
minval = min(minval, (int)cframe[k]);
maxval = max(maxval, (int)cframe[k]);
}
res = min(res, maxval - minval);
}
cout << res;
return 0;
}