首页 > 阿里笔试(0314算法岗)
头像
LightStar-
编辑于 2022-03-14 21:49
+ 关注

阿里笔试(0314算法岗) 投票 内部员工回复




时长:90分钟
总共6道单选+6道多选+3道编程

第一题:

比较简单,数据范围是1000,那么直接二层for循环模拟即可
#include<stdio.h>
int main()
{

    int a, b, c, d, m;
    scanf("%d %d %d %d %d", &a, &b, &c, &d, &m);
    int ans = 0, x, y;
    for (x = a; x <= b; x++)
        for (y = c; y <= d; y++)
            if (ans < (x * y) % m)
                ans = (x * y) % m;
    printf("%d\n", ans);
    return 0;
}


交换字符


这个题目出的很好,很多边界条件,组合数学
当交换2个相同的字符时,不会产生不同的字符串,因此我们可以用"所有交换的方案数" - "s 维持不变方案数"来得到答案
还要注意特判存在2个字母相同的情况,可以得到原串

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main() {
    string s; cin >> s;
    ll n = s.size(); 
    map<char, ll> M; for (auto ch: s) M[ch]++;
    ll tot = n*(n-1)/2;
    for (auto [k,v]: M) tot -= v*(v-1)/2;

    //存在2个相同的字母
    for (auto [k,v]: M) if (v >= 2) {
        tot++;
        break;
    }
    cout << tot << endl;
    
}



第三题:切割

第三题很难很难,最后才做出来:
做 2 次 dp
第一次 dp,求每个数模 k 等于 x,最少需要切割多少次 ;O(400x400x18)x 400` 个数
第二次 dp,用第一次dp 的结果,求前 i 个数模 k 等于 x,最少需要切割多少次,复杂度 O(400*400*400)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

vector<int> gao(ll n, int k) {
  string s = to_string(n);
  vector<vector<int>> dp(s.size()+1, vector<int>(k, 0x3f3f3f3f));
  dp[0][0] = 0;
  for (int i = 0; i < s.size(); i++) {
    int cur = 0;
    for (int j = i; j < s.size(); j++) {
      cur = (cur * 10 + s[j]-'0')%k;
      for (int x = 0; x < k; x++) {
        dp[j+1][(cur+x)%k] = min(dp[j+1][(cur+x)%k] , dp[i][x]+(i!=0));
      }
    }
  }
  return dp.back();
}

int main() {
  int n, k; cin >> n >> k;
  vector<ll> A(n); for (auto &x: A) cin >> x;
  vector<int> cur(k, 0x3f3f3f3f);
  cur[0] = 0;
  for (auto &t: A) {
    vector<int> nxt(k, 0x3f3f3f3f);
    vector<int> tmp = gao(t, k);
    for (int i = 0; i < k; i++) {
      for (int j = 0; j < k; j++) nxt[(i+j)%k] = min(nxt[(i+j)%k], cur[i]+tmp[j]); 
    }
    cur = nxt;
  }
  cout << cur[0] << endl;
}



全部评论

(13) 回帖
加载中...
话题 回帖