3.6阿里笔试

第一题
dp(i,j,k,l)表示第i列的数字排列情况是(j,k,l)的方案数,枚举下一列情况即可 复杂度O(n*27*27)
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <unordered_map>
#include <vector>
#define fir first
#define se second
#define ll long long
#define pb push_back
#define mp make_pair
#define ull unsigned long long
#define cl(a, b) memset(a, b, sizeof(a))
#define quickio(a) ios::sync_with_stdio(a)
#define datatest() freopen("data.in", "r", stdin)
#define makeans() freopen("data.out", "w", stdout)
#define makedata() freopen("data.in", "w", stdout)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pdd pair<double, double>
using namespace std;
const int maxn = 5e4 + 10;
const int maxm = 1e6 + 10;
const int inf = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const int maxblock = sqrt(maxn) + 10;
const double eps = 1e-7;
const ll INF = 1e16;
int n;
int dp[maxn][30];
int checklegal(int pos1, int pos2, int pos3, int i, int j, int k) {
  if (i == pos1 || j == pos2 || k == pos3) return false;
  return true;
}
int main() {
  int t;
  scanf("%d", &t);
  while (t--) {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
      for (int j = 0; j < 30; j++) {
        dp[i][j] = 0;
      }
    }
    for (int i = 1; i <= 3; i++) {
      for (int j = 1; j <= 3; j++) {
        if (i == j) continue;
        for (int k = 1; k <= 3; k++) {
          if (k == j) continue;
          dp[1][9 * (i - 1) + 3 * (j - 1) + (k - 1)] = 1;
        }
      }
    }
    for (int i = 2; i <= n; i++) {
      for (int pos1 = 1; pos1 <= 3; pos1++) {
        for (int pos2 = 1; pos2 <= 3; pos2++) {
          for (int pos3 = 1; pos3 <= 3; pos3++) {
            if (pos1 == pos2 || pos2 == pos3) continue;
            for (int i1 = 1; i1 <= 3; i1++) {
              for (int j1 = 1; j1 <= 3; j1++) {
                if (i1 == j1) continue;
                for (int k1 = 1; k1 <= 3; k1++) {
                  if (k1 == j1) continue;
                  // dp[1][9 * (i - 1) + 3 * (j - 1) + (k - 1)] = 1;
                  if (checklegal(pos1, pos2, pos3, i1, j1, k1)) {
                    int mask1 = 9 * (pos1 - 1) + 3 * (pos2 - 1) + (pos3 - 1);
                    int mask2 = 9 * (i1 - 1) + 3 * (j1 - 1) + (k1 - 1);
                    dp[i][mask2] = (dp[i][mask2] + dp[i - 1][mask1]) % mod;
                  }
                }
              }
            }
          }
        }
      }
    }
    ll res = 0;
    for (int i = 0; i < 30; i++) res = (res + dp[n][i]) % mod;
    printf("%lld\n", res);
  }
  return 0;
}

第二题
若两个地铁具有相同站点 就在这两个地铁连边 跑一遍floyd就可以了
tip:s==t的时候输出0 不管有没有线路
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <unordered_map>
#include <vector>
#define fir first
#define se second
#define ll long long
#define pb push_back
#define mp make_pair
#define ull unsigned long long
#define cl(a, b) memset(a, b, sizeof(a))
#define quickio(a) ios::sync_with_stdio(a)
#define datatest() freopen("data.in", "r", stdin)
#define makeans() freopen("data.out", "w", stdout)
#define makedata() freopen("data.in", "w", stdout)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pdd pair<double, double>
using namespace std;
const int maxn = 1e6 + 10;
const int maxm = 1e6 + 10;
const int inf = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const int maxblock = sqrt(maxn) + 10;
const double eps = 1e-7;
const ll INF = 1e16;
int n, S, T;
int w[510][510];
vector<int> g[510];
vector<int> line[510];
map<int, vector<int>> ma;
int dis[510][510];
int vis[510];
queue<int> q;
int main() {
  int t;
  scanf("%d", &t);
  while (t--) {
    scanf("%d %d %d", &n, &S, &T);
    for (int i = 0; i < 510; i++) line[i].clear(), g[i].clear();
    for (int i = 0; i < 510; i++) {
      for (int j = 0; j < 510; j++) w[i][j] = inf;
    }
    for (int i = 1; i <= n; i++) {
      int num;
      scanf("%d", &num);
      for (int j = 0; j < num; j++) {
        int a;
        scanf("%d", &a);
        line[i].pb(a);
      }
    }
    ma.clear();
    for (int i = 1; i <= n; i++) {
      for (auto &it : line[i]) {
        ma[it].pb(i);
      }
    }
    for (auto &it : ma) {
      auto &l = it.second;
      for (int i = 0; i < l.size(); i++) {
        for (int j = 0; j < l.size(); j++) {
          if (l[i] == l[j]) {
            // w[l[i]][l[i]] = 0;
            continue;
          }
          w[l[i]][l[j]] = 1;
          w[l[j]][l[i]] = 1;
        }
      }
    }

    for (int k = 1; k <= n; k++) {
      for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
          w[i][j] = min(w[i][j], w[i][k] + w[k][j]);
        }
      }
    }
    auto &l1 = ma[S];
    auto &l2 = ma[T];
    int Min = inf;
    for (auto &it1 : l1) {
      for (auto &it2 : l2) {
        if (it1 == it2) {
          Min = 1;
          continue;
        }
        Min = min(Min, w[it1][it2] + 1);
      }
    }

    if (S == T) {
      printf("0\n");
      continue;
    }
    assert(Min == inf || Min <= n);
    if (Min == inf) Min = -1;
    printf("%d\n", Min);
  }

  return 0;
}


#笔试题目##阿里巴巴#
全部评论
大佬两道全ac了吗,第一个题可以用快速幂数学方法做吗
1 回复 分享
发布于 2021-03-06 20:36
看这扑面而来的毒瘤宏定义,就知道是ACMer老哥
点赞 回复 分享
发布于 2021-03-07 00:31

相关推荐

5 8 评论
分享
牛客网
牛客企业服务