每天坚持写三道题第二天
今日题目:
目录
题目一:
题目大意:
现在有n张牌叠在一起,a1为牌顶,an为牌底
牌顶为第一张牌
每次操作中,可以选择以下操作中的一种进行:
1.从牌顶开始,选择第i张牌,其中i为奇数,那么可以把这张牌上的数字加到分数上,并且移除这张牌
2.从牌顶开始,选择第i张牌,其中i为偶数,移除这一张牌
3.选择停止操作,结束游戏
你可以进行任意次操作,请你求出你可以获得的分数最大值
解题思路:
我们可以注意到
当牌的数量大于3的时候
我们可以关注大于等于3位置之后的牌
我们拿所有第奇数张并且为正数的牌
并且不断的进行这个操作,然后加到分数上
操作到最后,会变成,奇数位置已经没有正数的牌了
那么现在的情况是:
所有为正数牌都是在偶数位置的
(这个应该是很容易证明的)
在这个情况下,如何拿到这些正数呢?
现在我们再关注位置1和位置2的牌
我们可以拿其中一张,拿完之后,后面的偶数位置都会变成奇数位置,现在可以把所有的正数拿到了
综上可以得出一个结论:在位置3以及之后的所有正数牌,都是可以拿到的
现在问题变成了,我们在前两张牌中,怎么拿可以让分数最大化
很容易可以发现:
我们设第一张牌为a,第二张牌为b
我们可以拿a,分数会加a, 然后b就变成第一张了,我们可以选择拿或者不拿
我们也可以选择只拿b,但是b不会加到分数上
综上可以得出总结论:
1.在位置3以及之后的所有正数牌,都是可以拿到的
2.位置1和位置2,可以只拿位置1,也就是分数只加位置1的分数,我们也可以都拿,分数加上位置1 + 2的分数,我们也可以拿2,但是不加分
代码(C++):
void solve() {
int n;
std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; i++) {
std::cin >> a[i];
}
i64 ans = 0;
for (int i = 2; i < n; i++) {
if (a[i] > 0) {
ans += a[i];
}
}
int cur;
if (n > 1) {
cur = std::max({0, a[0], a[1] + a[0]});
} else {
cur = std::max({0, a[0]});
}
std::cout << ans + cur << "\n";
}
题目二:
题目大意:
现在有n个人,每个人刚开始都有一个资产ai
现在给你t个查询
每次查询分为:
1 q x表示第q个人的资产现在为x
2 x表示把每个资产小于x的人的资产变成x
解题思路:
一道比较模拟的题目
我们可以注意到:
每个人最后一次变化后,只需要关注后面的"时间"出现的2 x,,每一个x和他现在的资产大小比较就行
并且我们可以发现只需要关注后面的最大的x即可
我们可以用后缀数组快速完成这个操作
一个人变换后,我们可以用一个数组来记录此时变换的"时间"
这样就可以快速求出最后一次变化后的资产了
模拟题,具体看代码实现
代码(C++):
void solve() {
int n;
std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; i++) {
std::cin >> a[i];
}
int q;
std::cin >> q;
std::vector<int> suf(q), change(n);
for (int t = 0; t < q; t++) {
int op;
std::cin >> op;
if (op == 1) {
int p, x;
std::cin >> p >> x;
p--;
a[p] = x;
change[p] = t;
} else {
int x;
std::cin >> x;
suf[t] = x;
}
}
for (int i = q - 2; i >= 0; i--) {
suf[i] = std::max(suf[i], suf[i + 1]);
}
for (int i = 0; i < n; i++) {
std::cout << std::max(a[i], suf[change[i]]) << " ";
}
}
题目三:
题目大意:
现在有一个机器人,通过一个指令进行移动
现在你可以在网格中放置一个障碍物,
如果机器人下一个移动指令会碰到这个障碍物
那么机器人不会进行此次移动
请问你是否可以放一个障碍物,让机器人回到原点
解题思路:
枚举模拟题
我们可以枚举机器人所能到的每一个位置
对于这个位置
我们可以在此刻放一个障碍物,然后再次移动,查看是否可以回到原点
我们可以把移动逻辑写成一个函数,这样就可以不用写两次移动逻辑了
模拟题,具体实现看代码
代码(C++):
void solve() {
std::string s;
std::cin >> s;
int n = s.size();
auto move = [&] (int &x, int &y, char c) -> void {
if (c == 'U') {
y++;
} else if (c == 'D') {
y--;
} else if (c == 'L') {
x--;
} else {
x++;
}
};
for (int i = 0; i < n; i++) {
int x = 0, y = 0;
for (int j = 0; j <= i; j++) {
move(x, y, s[j]);
}
int ans_x = x, ans_y = y;
x = 0, y = 0;
for (int j = 0; j < n; j++) {
int x1 = x, y1 = y;
move(x1, y1, s[j]);
if (x1 != ans_x || y1 != ans_y) {
x = x1;
y = y1;
}
}
if (x == 0 && y == 0) {
std::cout << ans_x << " " << ans_y << "\n";
return;
}
}
std::cout << "0 0\n";
}
Python语言写法:
题目一:
def solve():
n = int(input())
a = list(map(int, input().split()))
ans = 0
for i in range(2, n):
if a[i] > 0:
ans += a[i]
cur = 0
if n > 1:
cur = max(0, a[0], a[1] + a[0])
else:
cur = max(0, a[0])
print(ans + cur)
题目二:
def solve():
n = int(input())
a = list(map(int, input().split()))
q = int(input())
change = [0] * n
suf = [0] * q
for t in range(q):
A = list(map(int, input().split()))
if len(A) == 3:
A[1] -= 1
a[A[1]] = A[2]
change[A[1]] = t
else:
suf[t] = A[1]
for i in range(q - 2, -1, -1):
suf[i] = max(suf[i], suf[i + 1])
for i in range(n):
print(max(a[i], suf[change[i]]), end = " ")
题目三:
def solve():
s = input().strip()
n = len(s)
def move(x, y, c):
if c == 'U':
y += 1
elif c == 'D':
y -= 1
elif c == 'L':
x -= 1
else:
x += 1
return x, y
for i in range(n):
x, y = 0, 0
for j in range(i + 1):
x, y = move(x, y, s[j])
ans_x, ans_y = x, y
x, y = 0, 0
for j in range(n):
x1, y1 = x, y
x1, y1 = move(x1, y1, s[j])
if x1 != ans_x or y1 != ans_y:
x, y = x1, y1
if x == 0 and y == 0:
print(ans_x, ans_y)
return
print(0, 0)
Go语言写法:
题目一:
package main
import (
"bufio"
. "fmt"
"os"
)
var (
in = bufio.NewReader(os.Stdin)
out = bufio.NewWriter(os.Stdout)
)
func main() {
defer out.Flush()
var T int
for Fscan(in, &T); T > 0; T-- {
solve()
}
}
func solve() {
n := 0
Fscan(in, &n)
a := make([]int, n)
for i := range a {
Fscan(in, &a[i])
}
ans := 0
for i := 2; i < n; i++ {
if a[i] > 0 {
ans += a[i]
}
}
cur := 0
if n > 1 {
cur = max(0, a[0], a[0]+a[1])
} else {
cur = max(0, a[0])
}
Fprintln(out, ans+cur)
}
题目二:
package main
import (
"bufio"
. "fmt"
"os"
)
var (
in = bufio.NewReader(os.Stdin)
out = bufio.NewWriter(os.Stdout)
)
func main() {
defer out.Flush()
solve()
}
func solve() {
n := 0
Fscan(in, &n)
a := make([]int, n)
for i := range a {
Fscan(in, &a[i])
}
q := 0
Fscan(in, &q)
suf := make([]int, q)
change := make([]int, n)
for t := 0; t < q; t++ {
op := 0
Fscan(in, &op)
if op == 1 {
var p, x int
Fscan(in, &p, &x)
p--
a[p] = x
change[p] = t
} else {
x := 0
Fscan(in, &x)
suf[t] = x
}
}
for i := q - 2; i >= 0; i-- {
suf[i] = max(suf[i], suf[i+1])
}
for i, v := range a {
Fprint(out, max(v, suf[change[i]]), " ")
}
}
题目三:
package main
import (
"bufio"
. "fmt"
"os"
)
var (
in = bufio.NewReader(os.Stdin)
out = bufio.NewWriter(os.Stdout)
)
func main() {
defer out.Flush()
var T int
for Fscan(in, &T); T > 0; T-- {
solve()
}
}
func solve() {
var s string
Fscan(in, &s)
n := len(s)
move := func(x, y int, c rune) (int, int) {
switch c {
case 'U':
y++
case 'D':
y--
case 'L':
x--
case 'R':
x++
}
return x, y
}
for i := 0; i < n; i++ {
x, y := 0, 0
for j := 0; j <= i; j++ {
x, y = move(x, y, rune(s[j]))
}
ansX, ansY := x, y
x, y = 0, 0
for j := 0; j < n; j++ {
x1, y1 := x, y
x1, y1 = move(x1, y1, rune(s[j]))
if x1 != ansX || y1 != ansY {
x, y = x1, y1
}
}
if x == 0 && y == 0 {
Fprintf(out, "%d %d\n", ansX, ansY)
return
}
}
Fprintln(out, "0 0")
}