坚持每日Codeforces三题挑战:Day 2 - 题目详解(2025-04-15,难度:1500, 1600, 1600)

每天坚持写三道题第二天

今日题目:

Problem - C - Codeforces 1500

Problem - B - Codeforces 1600

Problem - K - Codeforces 1600

目录

题目一:

题目大意:

解题思路:

代码(C++):

题目二:

题目大意:

解题思路:

代码(C++):

题目三:

题目大意:

解题思路:

代码(C++):

Python语言写法:

题目一:

题目二:

题目三:

Go语言写法:

题目一:

题目二:

题目三:


题目一:

Problem - C - Codeforces

题目大意:

现在有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";
}

题目二:

Problem - B - Codeforces

题目大意:

现在有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]]) << " ";
    }
}

题目三:

Problem - K - Codeforces

题目大意:

现在有一个机器人,通过一个指令进行移动

现在你可以在网格中放置一个障碍物,

如果机器人下一个移动指令会碰到这个障碍物

那么机器人不会进行此次移动

请问你是否可以放一个障碍物,让机器人回到原点

解题思路:

枚举模拟题

我们可以枚举机器人所能到的每一个位置

对于这个位置

我们可以在此刻放一个障碍物,然后再次移动,查看是否可以回到原点

我们可以把移动逻辑写成一个函数,这样就可以不用写两次移动逻辑了

模拟题,具体实现看代码

代码(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")
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值