牛客周赛 Round 83


A. 和猫猫一起起舞!

点击查看代码
void solve() {
    std::string s;
    std::cin >> s;
    if (s == "U" || s == "D") {
    	std::cout << "L\n";
    } else {
    	std::cout << "U\n";
    }
}

B. 冒险猫猫参上!!

题意:构造一个数组,使得\(\forall i \in [1, n - 1], |a_i - a_{i+1}| = 1\),且总和不超过\(3 \times n\)

\(1, 2, 1, 2, ..\)这样放就行。

点击查看代码
void solve() {
    int n;
    std::cin >> n;
    for (int i = 0; i < n; ++ i) {
    	std::cout << (i % 2 ? 2 : 1) << " \n"[i == n - 1];
    }
}

C. 泉神,启动!!!

题意:给你一个\(x\),找一个大于\(1\)\(y\),使得\(x\times y\)各自数位上的数构成的集合是\(x\)各自数位上的数的集合的子集。

我们可以把两个\(x\)接到一起,那么假设\(x\)的最高位是\(10^i\)次幂,那么我们就要找\(10^{i+1} \times x + x\),发现这个数除上\(x\)就是\(10^{i+1} + 1\)

点击查看代码
void solve() {
    int n;
    std::cin >> n;
    i64 x = 1;
    while (x <= n) {
    	x *= 10;
    }

    x = x + 1;
    std::cout << x << "\n";
}

D. 大预言家!!!!

题意:按照题目给出的移动方式移动,求第\(t\)秒的坐标。

找规律题,发现走一段时间后路径就会转成一个正方形,大小分别是\(1 \times 1, 3 \times 3, 5 \times 5, ...\),也就是各个奇数的平方。那么二分找到\(t\)秒时在哪个正方形的外层。然后按运动方式走四条边模拟。

点击查看代码
void solve() {
    i64 t;
    std::cin >> t;
    i64 l = 1, r = 1e9;
    while (l < r) {
    	i64 mid = l + r + 1 >> 1ll;
    	if (mid * mid <= t) {
    		l = mid;
    	} else {
    		r = mid - 1;
    	}
    }

    i64 k = l;
    if (k % 2 == 0) {
    	-- k;
    }

    t -= k * k;
    i64 x = k / 2, y = k / 2;
    if (t == 0) {
    	std::cout << x << " " << y << "\n";
    	return;
    }

    k += 2;

    x += 1;
    t -= 1;

    i64 a = std::min(t, k - 2);
    y -= a;
    t -= a;
    a = std::min(t, k - 1);
    x -= a;
    t -= a;
    a = std::min(t, k - 1);
    y += a;
    t -= a;
    a = std::min(t, k - 1);
    x += a;
    std::cout << x << " " << y << "\n";
}

E. 全都要!!!!!

题意:给你一个长度为\(n\)的数组\(a\),第\(i\)个位置上有\(a_i\)的价值,你每次可以走\(1\)\(6\)步,求走\(k\)步后的最大总价值。

\(f[i][j]\)表示走到\(i\)时用了\(k\)步的最大价值。然后枚举上一步走了几步转移就行。

点击查看代码
void solve() {
    int n, k;
    std::cin >> n >> k;
    std::vector<int> a(n);
    for (int i = 0; i < n; ++ i) {
    	std::cin >> a[i];
    }

    const i64 inf = 1e18;
    std::vector f(n + 1, std::vector<i64>(k + 1, -inf));
    f[0][0] = 0;
    for (int i = 1; i <= n; ++ i) {
    	for (int j = 1; j <= k; ++ j) {
    		for (int x = 1; x <= std::min(6, i); ++ x) {
    			f[i][j] = std::max(f[i][j], f[i - x][j - 1] + a[i - 1]);
			}
    	}
    }

    i64 ans = -inf;
    for (int i = 1; i <= n; ++ i) {
    	ans = std::max(ans, f[i][k]);
    }

    std::cout << ans << "\n";
}

F. 水题!!!!!!

题意:有一个矩阵,水从源头开始流下来,遇到障碍物需要\(h\)秒破环它,水流移动一格需要一秒,如果当前水流是垂直向下的并且遇上了障碍物,那么会同时向左右两边流,左右两边的水流不会摧毁下面的障碍物,并且只有遇到下面没有障碍物的情况才会往下流,这时这股水流又可以摧毁障碍物。求到终点的最小时间。

\(dist[x][y][t], t \in \{0, 1\}\)为水流在\((x, y)\)时不可以\(/\)可以摧毁障碍物的最小时间。那么就分情况看,如果下面没有障碍物就只能往下,否则看能不能摧毁障碍物,能就花\(h + 1\)秒到下面。然后往两边扩展,注意如果一个\(t=0\)的水流往下流那么到下面一格\(t=1\)
\(dijkstra\)即可。

点击查看代码
void solve() {
    int n, m, h;
    std::cin >> n >> m >> h;
    std::vector<std::string> s(n);
    for (int i = 0; i < n; ++ i) {
    	std::cin >> s[i];
    }

    int sx, sy, tx, ty;
    for (int i = 0; i < n; ++ i) {
    	for (int j = 0; j < m; ++ j) {
    		if (s[i][j] == '*') {
    			sx = i, sy = j;
    		} else if (s[i][j] == '%') {
    			tx = i, ty = j;
    		}
    	}
    }

    const i64 inf = 1e18;
    std::vector dist(n, std::vector(m, std::array<i64, 2>{inf, inf}));
    using A = std::array<i64, 4>;
    std::priority_queue<A, std::vector<A>, std::greater<A>> heap;
    dist[sx][sy][1] = 0;
    heap.push({dist[sx][sy][1], sx, sy, 1});
    while (heap.size()) {
    	auto [d, x, y, t] = heap.top(); heap.pop();
    	// std::cout << d << " " << x + 1 << " " << y + 1 << " " << t << "\n";
    	if (d != dist[x][y][t]) {
    		continue;
    	}

		if (x + 1 < n) {
    		if (t == 1 && s[x + 1][y] == '#' && dist[x + 1][y][1] > dist[x][y][t] + h + 1) {
    			dist[x + 1][y][1] = dist[x][y][t] + h + 1;
    			heap.push({dist[x + 1][y][1], x + 1, y, 1});
    		} else if ((s[x + 1][y] == '.' || s[x + 1][y] == '%') && dist[x + 1][y][1] > dist[x][y][t] + 1) {
    			dist[x + 1][y][1] = dist[x][y][t]+ 1;
    			heap.push({dist[x + 1][y][1], x + 1, y, 1});
    		}

    		if (s[x + 1][y] == '#' && y + 1 < m && (s[x][y + 1] == '.' || s[x][y + 1] == '%') && dist[x][y + 1][0] > dist[x][y][t] + 1) {
    			dist[x][y + 1][0] = dist[x][y][t] + 1;
    			heap.push({dist[x][y + 1][0], x, y + 1, 0});
    		}

    		if (s[x + 1][y] == '#' && y - 1 >= 0 && (s[x][y - 1] == '.' || s[x][y - 1] == '%') && dist[x][y - 1][0] > dist[x][y][t] + 1) {
    			dist[x][y - 1][0] = dist[x][y][t] + 1;
    			heap.push({dist[x][y - 1][0], x, y - 1, 0});
    		}
		}
    }

    i64 ans = std::min(dist[tx][ty][0], dist[tx][ty][1]);
    if (ans == inf) {
    	ans = -1;
    }

    std::cout << ans << "\n";
}
posted @ 2025-03-02 21:01  maburb  阅读(45)  评论(0)    收藏  举报