2019 第 10 届蓝桥杯省赛 A 组

题目链接

题解

水题较多。

D: 迷宫

  bfs 裸题。

1
DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
using namespace std;

#define debug(x) cout << #x << " is " << x << endl
#define inc(i, a, b) for (int i = a; i <= b; ++i)
typedef long long ll;
const int INF = 0x3f3f3f3f, N = 35, M = 55;
const int n = 30, m = 50;

struct node {
    int x, y;
    node (int x, int y) : x(x), y(y) {}
};

int dx[] = {1, 0, 0, -1}, dy[] = {0, -1, 1, 0};
int vis[N][M], dir[N][M];
char maze[N][M], str[5] = "DLRU", ans[N * M];

void bfs() {
    queue<node> q;
    q.push(node(1, 1));
    vis[1][1] = 0;
    while (!q.empty()) {
        node tmp = q.front();
        q.pop();
        for (int i = 0; i < 4; ++i) {
            int tx = tmp.x + dx[i];
            int ty = tmp.y + dy[i];
            if (tx < 1 || tx > n || ty < 1 || ty > m || vis[tx][ty] || maze[tx][ty] == '1') continue;
            vis[tx][ty] = 1;
            dir[tx][ty] = i;
            q.push(node(tx, ty));
        }
    }
}

int main() 
{
    freopen("maze.txt", "r", stdin);
    for (int i = 1; i <= 30; ++i) {
        scanf("%s", maze[i] + 1);
    }
    bfs();
    int x = n, y = m, cnt = 0;
    while (x != 1 || y != 1) {
        int k = dir[x][y];
        ans[++cnt] = str[k];
        x -= dx[k], y -= dy[k];
    }
    for (int i = cnt; i >= 1; --i) {
        printf("%c", ans[i]);
    }
    puts("");
    return 0;
}

E: RSA 解密

  思维难度不大,需要熟悉一些数学操作。

$$d\times e-k\times(p-1)(q-1)=1$$

答案: 579706994112328949

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;

#define debug(x) cout << #x << " is " << x << endl
#define inc(i, a, b) for (int i = a; i <= b; ++i)
typedef long long ll;
const int INF = 0x3f3f3f3f;

void exgcd(ll a, ll b, ll &x, ll &y) {
	if (!b) x = 1, y = 0;
	else exgcd(b, a % b, y, x), y -= a / b * x;
}

inline ll mul(ll x, ll y, ll p) { // 会爆 long long
	ll z = (long double)x / p * y;
	ll res = (unsigned long long)x * y - (unsigned long long)z * p;
	return (res + p) % p;
}

ll qpow(ll a, ll x, ll p) {
	a %= p;
	ll res = 1;
	for (; x; x >>= 1, a = mul(a, a, p))
		if (x & 1) res = mul(res, a, p);
	return res;
}

int main() 
{
	ll n = 1001733993063167141, d = 212353, c = 20190324, p, q;
	/*for (ll i = 3; i * i < n; i += 2) {
		if (n % i == 0) {
			p = i;
			q = n / i;
			break;
		}
	}
	printf("p = %lld, q = %lld;\n", p, q);*/
	p = 891234941, q = 1123984201;
	ll m = (p - 1) * (q - 1), x, y, e;
	exgcd(d, m, x, y);
	e = (x % m + m) % m;
	printf("%lld\n", qpow(c, e, n));
    return 0;
}

F: 完全二叉树的权值

  完全二叉树求哪个深度的节点权值之和最大。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;

#define debug(x) cout << #x << " is " << x << endl
typedef pair<int, int> pii;
typedef long long ll;
const int INF = 0x3f3f3f3f, N = 1e5 + 5;
const ll inf = 0x3f3f3f3f3f3f3f3f;

int n, cnt;

int main() 
{
	scanf("%d", &n);
	int depth = 0, ans = 0;
	ll res = -inf, x;
	while (cnt < n) {
		ll sum = 0;
		for (int i = 0; i < (1<<depth); ++i) {
			scanf("%lld", &x);
			sum += x;
			if (++cnt >= n) break; 
		}
		if (sum > res) res = sum, ans = depth + 1; 
		depth++;
	}
	printf("%d\n", ans);
    return 0;
}

G: 外卖店优先级

  理清题意,最后三种情况 $t$ 时刻外卖店在优先缓存中。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;

#define debug(x) cout << #x << " is " << x << endl
typedef pair<int, int> pii;
typedef long long ll;
const int INF = 0x3f3f3f3f, N = 1e5 + 5;

int n, m, t, ans;
vector<int> q[N];

int main() 
{
	scanf("%d%d%d", &n, &m, &t);
	int ts, id;
	while (m--) {
		scanf("%d%d", &ts, &id);
		q[id].push_back(ts);
	}
	for (int i = 1; i <= n; ++i) {
		sort(q[i].begin(), q[i].end());
		int lst = 0, pri = 0;
		for (int ts : q[i]) {
			if (ts - lst >= 1) pri -= (ts - lst - 1);
			pri = max(0, pri);
			pri += 2;
			lst = ts;
		}
		pri -= (t - lst);
		if (pri > 5 || (pri == 5 && lst != t) || (pri == 4 && lst < t - 1)) ans++;
	}
	printf("%d\n", ans);
    return 0;
}

H: 修改数组

  并查集。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;

#define debug(x) cout << #x << " is " << x << endl
typedef pair<int, int> pii;
typedef long long ll;
const int INF = 0x3f3f3f3f, N = 11e5 + 5;

int n;
int fa[N], vis[N];

int find(int x) {
	if (x == fa[x]) return x;
	return fa[x] = find(fa[x]);
}

int main() 
{
	scanf("%d", &n);
	for (int i = 1; i < N; ++i) fa[i] = i;
	int x;
	for (int i = 1; i <= n; ++i) {
		scanf("%d", &x);
		int ans = vis[x] ? find(x) + 1 : x;
		printf("%d ", ans);
		vis[ans] = 1;
		if (ans != 1 && vis[ans-1]) fa[ans-1] = ans;
		if (vis[ans+1]) fa[ans] = ans + 1; 
	}
    return 0;
}

I: 糖果

  状压裸题。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;

#define debug(x) cout << #x << " is " << x << endl
typedef pair<int, int> pii;
typedef long long ll;
const int INF = 0x3f3f3f3f, N = 105;

int n, m, k;
int a[N], f[1<<20];

int main() 
{
	scanf("%d%d%d", &n, &m, &k);
	int x;
	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= k; ++j) {
			scanf("%d", &x);
			a[i] |= 1 << (x - 1);
		}
	}
	memset(f, 0x3f, sizeof(f));
	f[0] = 0;
	for (int i = 1; i <= n; ++i) {
		for (int s = 0; s < 1 << m; ++s) {
			f[s|a[i]] = min(f[s|a[i]], f[s] + 1);
		}
	}
	printf("%d\n", f[(1<<m)-1] == INF ? -1 : f[(1<<m)-1]);
    return 0;
}

J: