美团8.12 后端笔试代码
美团8.12 后端笔试代码
第一题:
给一个x和y,问它们在数组中是否相邻
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n; cin >> n;
vector<int> vec(n);
for(auto &c : vec){
cin >> c;
}
int x, y; cin >> x >> y;
bool f = false;
for(int i = 0; i < n-1;i++){
if(vec[i] == x && vec[i+1] == y || vec[i] == y && vec[i+1] == x){
f = true;
break;
}
}
if(f){
cout << "Yes\n";
}else{
cout << "No\n";
}
}
第二题:
给一个x和y(下标从1到n),以及一个环形数组,数组a[i] 表示第i个点到第i+1个点的距离,求x到y的最短距离
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
using ll = int64_t;
int main() {
int n;
cin >> n;
vector<ll> vec(n);
for (auto& c : vec) {
cin >> c;
}
ll x, y;
cin >> x >> y;
x--, y--;
ll ans = 1e9;
if (x > y) {
ll mx1 = 0, mx2 = 0;
for (int i = y; i < x; i++) {
mx1 += vec[i];
}
for (int i = x; i < n; i++) {
mx2 += vec[i];
}
for (int i = 0; i < y; i++) {
mx2 += vec[i];
}
ans = min(mx1, mx2);
} else {//x < y
ll mx1 = 0, mx2 = 0;
for (int i = x; i < y; i++) {
mx1 += vec[i];
}
for (int i = y; i < n; i++) {
mx2 += vec[i];
}
for (int i = 0; i < x; i++) {
mx2 += vec[i];
}
ans = min(mx1, mx2);
}
cout <<ans;
}
// 64 位输出请用 printf("%lld")
第三题
给你一个二维数组,你需要横线切一刀或者竖向切一刀,将其分为两块(记作a,b),
求两数组的和之间的最小的差值(即abs(sumA - sumB)
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
using ll = int64_t;
ll n, m, s1 = 0, s2 = 0, sum = 0;
const int N = 1e3+10;
ll a[N][N];
int main() {
//一刀,二维前缀和问题
cin >> n >> m;
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
cin >> a[i][j];
sum += a[i][j];
}
}
for(int i = 1; i < n; i++){
a[i][0] += a[i-1][0];
}
for(int j = 1; j < m; j++){
a[0][j] += a[0][j-1];
}
for(int i = 1; i < n; i++){
for(int j = 1; j < m; j++){
a[i][j] += a[i-1][j] + a[i][j-1] - a[i-1][j-1];
}
}
ll ans = 1e18;
for(int i = 0; i < n; i++){
//ll preSum = a[i][m-2] + a[i-1][m-1] - a[i-1][m-2];
ans = min(ans, abs(a[i][m-1] - (sum - a[i][m-1])));
}
for(int j = 0; j < m; j++){
//ll preSum = a[n-1][j-1] + a[i-1][j] -
ans = min(ans, abs(a[n-1][j] - (sum - a[n-1][j])));
}
cout << ans << endl;
}
// 64 位输出请用 printf("%lld")
第四题
给你一个长度为n的字符串,然后你可以将其分为x*y = n的二维数组,当四个方向字符相同时为联通块,求最小的连通块个数
不懂啊,为啥我才60%,盯了40分钟也没看出来,希望有大佬可以给我说一下
好吧已经有大佬点醒我了,我只计算了nm中n<=m的情况
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
using ll = int64_t;
const int N = 1e3+10;
const int dx[] = {0, 0, 1, -1}, dy[] = {1, -1, 0, 0};
int nn, mm, ans = 1e9, every = 0;
void dfs(int x, int y, vector<vector<char>> &g, vector<vector<int>> &vis){
vis[x][y] = 1;
for(int i = 0; i < 4; i++){
int nx = x + dx[i], ny = y + dy[i];
if(nx < 0 || nx >= nn || ny < 0 || ny >= mm) continue;
if(vis[nx][ny] == 1 || g[x][y] != g[nx][ny]) continue;
vis[nx][ny] = 1;
dfs(nx, ny, g, vis);
}
}
void calc(vector<vector<char>> &g, vector<vector<int>> &vis){
for(int i = 0; i < nn; i++){
for(int j = 0; j < mm; j++){
if(vis[i][j] == 0) {
vis[i][j] = 1;
dfs(i, j, g, vis);
every ++;
}
}
}
}
int main() {
int n; cin >> n;
string s; cin >> s;
vector<int> yinzi;
for(int i = 1; i * i <= n; i++){
if(n % i == 0) yinzi.push_back(i);
}
for(int c : yinzi){
nn = n / c, mm = c;
vector<vector<char>> g(nn, vector<char>(mm));
vector<vector<int>> vis(nn, vector<int>(mm, 0));
for(int i = 0; i < nn; i++){
for(int j = 0; j < mm; j++){
g[i][j] = s[i * mm + j];
// cout << g[i][j];
}
// cout << endl;
}
//cout << endl;
every = 0;
//memset(vis, 0, sizeof(vis));
calc(g, vis);
ans = min(every, ans);
}
cout << ans;
}
// 64 位输出请用 printf("%lld")
第五题
给你一颗树,一开始节点颜色都是黑色,每个节点都有一个权值,当两个相邻节点的乘积为完全平方数时,你可以将他们同时染成红色,求这颗树中,你最多能得到多少红色节点
print(0) //6.67%#笔试#
上海得物信息集团有限公司公司福利 1186人发布