2020中南大学研究生招生夏令营机试题

170 阅读1分钟

传送门

1252: 缺失的彩虹-模拟

众所周知,彩虹有7种颜色,我们给定七个 字母和颜色 的映射,如下所示:
'A' -> "red"
'B' -> "orange"
'C' -> "yellow"
'D' -> "green"
'E' -> "cyan"
'F' -> "blue"
'G' -> "purple"
但是在某一天,彩虹的颜色少了几种,你能告诉PIPI哪些彩虹的颜色没有出现过吗?

  • 简单模拟题
#include <bits/stdc++.h>

using namespace std;
string str[] = {"",      "red",  "orange", "yellow",
                "green", "cyan", "blue",   "purple"};
char a[] = {'#', 'A', 'B', 'C', 'D', 'E', 'F', 'G'};
int st[10];
map<string, int> mp;
int main() {
  int n;

  while (cin >> n) {
    memset(st, 0, sizeof st);
    mp.clear();
    int cnt = 0;
    while (n--) {
      string s;
      cin >> s;
      if (!mp[s]) {
        mp[s] = 1;
        for (int i = 1; i <= 7; i++) {
          if (s == str[i]) {
            st[i] = 1;
            cnt++;
            break;
          }
        }
      }
    }
    cout << 7 - cnt << endl;

    for (int i = 1; i < 8; i++) {
      if (!st[i]) {
        cout << a[i] << endl;
      }
    }
  }
  return 0;
}

1253: 最小价值和

1254: PIPI上学路-dp

PIPI每天早上都要从CSU的某个位置走到另一个位置。CSU可以抽象为一个n*m的方格。PIPI每天都要从(x1,y1)走到(x2,y2),规定每次可以向下或者向右移动一格。总共有q次询问,每次询问从(x1,y1)走到(x2,y2)有多少条不同的路径,答案对1000000007取模。

1. dfs深度优先遍历-时间复杂度O(mnqm*n*q)超时

`

#include <bits/stdc++.h>

using namespace std;

const int N = 5010;
int p = 1000000007;

int st[N][N];
int sx1, sy1, tx2, ty2;
int cnt;
int n, m, q;
int dx[] = {0, 1}, dy[] = {1, 0};

void dfs(int u, int v) {
  st[u][v] = 1;
  if (u == tx2 && v == ty2) {
    cnt++;
    cnt = cnt%p;
     st[u][v] = 0;
     return;
  }

  for (int i = 0; i < 2; i++) {
    int xx = u + dx[i], yy = v + dy[i];

    if (xx >= 1 && xx <= n && yy >= 1 && yy <= m && !st[xx][yy]) {
      dfs(xx, yy);
    }
  }
  st[u][v] = 0;
}
int main() {
  while (scanf("%d %d %d",&n,&m,&q)) {
    while (q--) {
       cnt = 0;
      memset(st, 0, sizeof st);
      //cin >> sx1 >> sy1 >> tx2 >> ty2;
         scanf("%d %d %d %d", &sx1, &sy1, &tx2, &ty2);
      dfs(sx1, sy1);
      printf("%d\n",cnt);
    }
  }
  return 0;
}

2. 动态规划
  • dp[i][j]表示从(1,1)到(i,j)的路径数。
  • 初始化 for (int i = 1; i < N; i++) { dp[1][i] = dp[i][1] = 1; }
  • 递推: dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % p;

技巧:转化,将(x1,y1)平移到(1,1),(x2,y2)也平移相同方位,最终结果dp[x2 - (x1 - 1)][y2 - (y1 - 1)]

注意点:内存限制128MB约等于10810^8B,防止运行错误(内存超出)、用scanf输入防止超时。

#include <bits/stdc++.h>

using namespace std;

const int N = 5005;
int p = 1000000007;
int n, m, q;
int dp[N][N];

int main() {
  // 初始化
  for (int i = 1; i < N; i++) {
    dp[1][i] = dp[i][1] = 1;
  }

  for (int i = 2; i < N; i++) {
    for (int j = 2; j < N; j++) {
      dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % p;
    }
  }

  while (scanf("%d %d %d", &n, &m, &q) != EOF) {
    while (q--) {
      int x1, y1, x2, y2;
      scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
      printf("%d\n", dp[x2 - (x1 - 1)][y2 - (y1 - 1)]);
    }
  }
  return 0;
}