首页 > 编程语言 >Codeforces Round 962 (Div. 3) A - D详细题解(思路加代码Python,C++(垃圾灰名小白想写题解)

Codeforces Round 962 (Div. 3) A - D详细题解(思路加代码Python,C++(垃圾灰名小白想写题解)

时间:2024-07-28 09:28:59浏览次数:13  
标签:小白想 cnt 962 int 题解 vector func res row

         吐槽一下,这次比赛不知道怎么的,可能是div3参加的人比较多吗,代码题解上去后全是in queue,比赛的过程中我还看了提交的,80多页几千个提交全是in queue, 我的代码等了**半个多小时才运行,然后发现time limit真的有点搞心态,思路在下一题我还要反过来去优化上一题,不过还是自己太菜了,能力够强的话直接半小时全部提交等ak了

比赛链接

Dashboard - Codeforces Round 962 (Div. 3) - Codeforces

题目A

链接:

Problem - A - Codeforces

题目大意理解:

输入一个数字n,表示总共的腿的数量

农场只有鸡和牛

输出一个数字,表示最少有多少个动物

思路:

知道腿的数量,要使动物数量最少,那就假设全是牛,剩下的就是鸡

而且要么n能整除4,要么余数是2,那么答案就是(n + 2) / 4

代码(Python):

'''
要么n能整除4,要么余数是2,那么答案就是(n + 2) // 4
'''
def func(n: int) -> int:
    return (n + 2) // 4
 
def main():
    t = II()
    result = []
    '''
    输入一个数字n,表示总共的腿的数量
    农场只有鸡和牛
    输出一个数字,表示最少有多少个动物
    '''
    for _ in range(t):
        n = II()
        res = func(n)
        result.append(res)
    for res in result:
        print(res)
if __name__ == "__main__":
    main()

代码(C++):

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

typedef long long ll;
/*
要么n能整除4,要么余数是2,那么答案就是(n + 2) / 4
*/
int func(int n) {
    return (n + 2) / 4;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t;
    cin >> t;
    /*
    输入一个数字n,表示总共的腿的数量
    农场只有鸡和牛
    输出一个数字,表示最少有多少个动物
    */
    while (t--){
        int n;
        cin >> n;
        int res = func(n);
        cout << res << '\n';
    }
}

题目B

链接:

​​​​​​Problem - B - Codeforces

题目大意理解:

第一行输入两个数n, k表示矩阵宽度和缩减范围

下面n行输入矩阵

对于这个矩阵,缩减范围内的数字都是相同的,把缩减范围的数字变成一个

好吧,说的有点抽象,用例子理解就好了,题目中也给出了图帮助理解

比如输入

6 3

000111

000111

000111

111000

111000

111000

操作后:

01

10

输出操作后的矩阵

思路:

遍历矩阵,每次加k,遇到的数字是什么就加入新的矩阵中去即可

代码(Python):

from typing import List

def func(arr: List[List[int]], k: int) -> List[list[int]]:
    n = len(arr)
    res = []
    for i in range(0, n, k):
        #一行一行的计算
        row = []
        for j in range(0, n, k):
            #当前数字
            cur_num = arr[i][j]
            row.append(cur_num)
        res.append(row)
    return res
    
def main():
    t = II()
    result = []
    for _ in range(t):
        n, k = MII()
        arr = []
        for _ in range(n):
            #这题有点小坑(也可能是我太蠢了),这个输入的没有空格
            #不能直接使用def LII():return list(MII())
            row = list(input())
            arr.append([int(x) for x in row])
        res = func(arr, k)
        result.append(res)

    for res in result:
        for row in res:
            for num in row:
                print(num, end ='')
            print()
if __name__ == "__main__":
    main()

代码(C++):

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

typedef long long ll;

vector<vector<int>> func(vector<vector<int>> arr, int k) {
    int n = arr.size();
    vector<vector<int>> res;
    for (int i = 0; i < n; i += k){
        vector<int> row;
        for (int j = 0; j < n; j += k){
            int curNum = arr[i][j];
            row.push_back(curNum);
        }
        res.push_back(row);
    }
    return res;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t;
    cin >> t;
    while (t--){
        int n, k;
        cin >> n >> k;
        vector<vector<int>> arr(n, vector<int>(n));
        for (int i = 0; i < n; i++){
            string row;
            cin >> row;
            for (int j = 0; j < n; j++){
                arr[i][j] = row[j] - '0';
            }
        }
        vector<vector<int>>res = func(arr, k);
        for (auto row : res){
            for(auto n : row){
                cout << n;
            }
            cout << '\n';
        }
    }
}

题目C

链接:

Problem - C - Codeforces

题目大意理解:

输入第一行两个数字n, q分别表示字符串长度和查询次数

接下来两行,输入两行字符串a, b 接下来

q行每行输入两个数l, r表示查询区间

sort[a[l...r]]表示对区间[a_l - 1, a_r - 1]中

对字符串进行排序,字典序小的在前面

 一次操作:

可以选择一个在区间内一个字符变成任何一个想要的字符

经过若干次操作,使得sort[a[l...r]] == sort[b[l...r]]

输出最小操作次数

思路:

首先理解这个sort

只要字符串里面的含有的字符个数和类型都相同,排序后两个字符串就是相等的

那么现在只需要统计l, r这个区间内的字符串不同的个数即可

可以用一个长度26的数组进行统计

可以对每一次操作直接暴力统计:

#这个方法每次查询都要遍历同一个字符串某个区间,当查询次数过多会超时的
def func_time_limit(a: str, b: str, l: int, r: int) -> int:
    a = a[l - 1:r]
    b = b[l - 1:r]
    if a == b:
        return 0
    cnt1 = [0] * 26
    cnt2 = [0] * 26
    for c in a:
        cnt1[ord(c) - ord('a')] += 1
    for c in b:
        cnt2[ord(c) - ord('a')] += 1
    #相同的个数
    cnt = sum(min(cnt1[i], cnt2[i]) for i in range(26))
    return len(a) - cnt

这个方法每次查询都要遍历同一个字符串某个区间,当查询次数过多会超时的

得想一个新的思路,既然每次都会查询同一个字符串的每个区间,那么可以用类似前缀和的思想

写一个函数,对一个长度为n的字符串生成一个行数为n + 1列数为26二维数组,这个二维数组每一行表示字符串每个下标前面所拥有的字符串个数和类型

然后每次查询就只需要对这个二维数组进行操作即可

代码(Python):

def pre(s: str) -> List[List[int]]:
    n = len(s)
    cnt = [[0] * 26 for _ in range(n + 1)]
    for i in range(1, n + 1):
        #复制上一行,然后在这一行添加字符串s的当前字符
        cnt[i] = cnt[i - 1].copy()
        cnt[i][ord(s[i - 1]) - ord('a')] += 1
    return cnt
 
def func(cnt_a: List[list[int]], cnt_b: List[List[int]], l: int, r: int):
    cnt = 0
    for i in range(26):
        #求出a和b在这个区间的字符个数即可
        a = cnt_a[r][i] - cnt_a[l - 1][i]
        b = cnt_b[r][i] - cnt_b[l - 1][i]
        #相同的个数就是a和b之间的最小值
        cnt += min(a, b)
    return r - l + 1 - cnt
 
def main():
    t = int(input())
    result = []
    for _ in range(t):
        n, q = map(int, input().split())
        a = input()
        b = input()
        #生成一个二维前缀数组
        cnt_a = pre(a)
        cnt_b = pre(b)
        for _ in range(q):
            l, r = map(int, input().split())
            result.append(func(cnt_a, cnt_b, l, r))
    
    for res in result:
        print(res)
 
if __name__ == "__main__":
    main()

代码(C++):

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

vector<vector<int>> pre(string& s) {
    int n = s.length();
    vector<vector<int>> cnt(n + 1, vector<int>(26, 0));
    for (int i = 1; i <= n; i++) {
        cnt[i] = cnt[i - 1];
        cnt[i][s[i - 1] - 'a']++;
    }
    return cnt;
}

int func(vector<vector<int>>& cnt_a, vector<vector<int>>& cnt_b, int l, int r) {
    int res = 0;
    for (int i = 0; i < 26; i++) {
        int diff_a = cnt_a[r][i] - cnt_a[l - 1][i];
        int diff_b = cnt_b[r][i] - cnt_b[l - 1][i];
        res += min(diff_a, diff_b);
    }
    return r - l + 1 - res;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    vector<int> result;
    while (t--) {
        int n, q;
        cin >> n >> q;
        string a, b;
        cin >> a >> b;
        vector<vector<int>> cnt_a = pre(a);
        vector<vector<int>> cnt_b = pre(b);
        while (q--) {
            int l, r;
            cin >> l >> r;
            result.push_back(func(cnt_a, cnt_b, l, r));
        }
    }
    for (int res : result) {
        cout << res << '\n';
    }
    return 0;
}

题目D

链接:

Problem - D - Codeforces

题目大意理解:

输入两个数n, x

然后找出满足条件的三元组的个数(a, b, c)

这三元组是有顺序的,比如(1,1,2)和(1,2,1)算两个

满足:ab+ac+bc≤n && 

标签:小白想,cnt,962,int,题解,vector,func,res,row
From: https://blog.csdn.net/2401_83669813/article/details/140733865

相关文章

  • 逆序对的数量 - 题解
    逆序对的数量时间限制:C/C++1000MS,其他语言2000MS内存限制:C/C++64MB,其他语言128MB描述给定一个长度为\(n\)的整数数列,请你计算数列中的逆序对的数量。逆序对的定义如下:对于数列的第\(i\)个和第\(j\)个元素,如果满足\(i<j\)且\(a[i]>a[j]\),则其为一个逆序对;否则......
  • ABC364题解(D-G)
    D先对\(a\)从小到大排序。将题目转化成找到最小的\(d\),使得恰好有\(k\)个\(a_i\in[b-d,b+d]\)。对于每个询问\(b,k\),考虑二分答案。设待检查的答案为\(d\),二分找到最小的\(p1\)使得\(a_{p1}\geqb-d\)和最小的\(p2\)使得\(a_{p2}>b+d\),包含的数的个数即为\(......
  • 题解:P10481 Sudoku
    Sudoku来自蓝书思路优化搜索顺序,位运算常数优化。优化搜索顺序数独问题的搜索很简单,“搜索状态”就是每个位置上填了什么数。在每个状态下,选择一个未填位置,检查那些填入仍能满足数独条件(合法)的数字。构成的新的局面即为该状态的“分支”。足够暴力的写法为依次对每个位置进......
  • 2023CSP-j复赛题解
    csp-j题解update:2024.6.18-2024.6.25:重构题解第一题:小苹果原题洛谷P9748思路n表示当前长度求几天取完:每天取走\((n-1)/3+1\)个苹果,记录几天取完第\(n\)个苹果第几天被取走:当\(n\bmod3=0\)时被取走时间复杂度约为\(O(\log_n)\)#include<iostream>......
  • [ARC105C] Camels and Bridge 题解
    [ARC105C]CamelsandBridge题解出自梦熊比赛后,梦熊比赛出原题了,忘周知。也许更好的阅读体验思路全排列,差分约束,二分。全排列\(n\leq8\),且要指定顺序,易想到用全排列枚举所有状态。差分约束在全排列之后,需要求得每种状态的最短距离。定义所有骆驼的编号的集合为\(S\)......
  • ABC 364 F - Range Connect MST 题解
    一副扑克牌,去掉1到K,剩下就是我,赛后十秒过,我是joker。......
  • CF613E Puzzle Lover 题解
    Description给定一个\(2\timesn\)的矩阵,每个位置上有一个小写字母。有一个长度为\(k\)的小写字符串\(w\),询问矩阵中有多少条有向路径满足以下条件:路径上的字母连起来恰好为\(w\)。不多次经过同一个位置。只能向上下左右四个方向走。\(n,k\le2\times10^3\),答案......
  • IOI2022 邮局 加强版 题解
    [IOI2000]邮局加强版题解考虑动态规划,设\(f_{i,j}\)为经过了\(i\)个村庄,正在建第\(j\)​个邮局的最优距离。以及\(w_{i,j}\)表示区间\([i,j]\)​内建一个邮局时的距离总和。\(a\)数组表示每个村庄的坐标编号。朴素版状态转移方程:\[f_{i,j}=\min(f_{i,j},f_{k,j......
  • 07-25 题解
    07-25题解原题出处(按顺序):CF1556ECF1234FP9746CF1316EP3651CF17CCF1842HA转化:括号序列如果\(a_i\>b_i\),则有\(a_i-b_i\)个左括号如果\(a_i\<b_i\),则有\(b_i-a_i\)个右括号(第一个+1的位置一定在第一个-1的位置的左侧,所以情况一用左括号......
  • Codeforces Round 962 (Div. 3) CDE
    时间:2024-07-27C.Sort原题:C.Sort标签:前缀和题意给定字符串a,b定义\(sorted(a[l..r])\)表示将a的lr区间排序为有序有q次询问,每次给出区间l,r,要求通过操作使\(sorted(a[l..r])==sorted(b[l..r])\)操作为将\(a_i\)变成需要的任意字符,求最少次数思路一开始由于是div3,尝......