牛客周赛 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. 冒险猫猫参上!!

题意:构造一个数组,使得i[1,n1],|aiai+1|=1,且总和不超过3×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,找一个大于1y,使得x×y各自数位上的数构成的集合是x各自数位上的数的集合的子集。

我们可以把两个x接到一起,那么假设x的最高位是10i次幂,那么我们就要找10i+1×x+x,发现这个数除上x就是10i+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×1,3×3,5×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个位置上有ai的价值,你每次可以走16步,求走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{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 @   maburb  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示