Codeforces Round 962 (Div. 3)(A - D)

锐评

这次感觉还不错,相比于div2难度相差蛮大,找回些自信心。

A.Legs

题目大意

农夫约翰的农场又迎来了美好的一天。

农夫约翰来到农场后,数了数 n n n 条腿。众所周知,农场里只住着鸡和牛,鸡有 2 2 2 条腿,而牛有 4 4 4 条腿。

假设约翰农场主数清了所有动物的腿,那么他的农场里最少有多少动物?

输入描述

第一行包含一个整数 t t t ( 1 ≤ t ≤ 1 0 3 1 \leq t \leq 10^3 1t103 ) - 测试用例数。

每个测试用例包含一个整数 n n n 2 ≤ n ≤ 2 ⋅ 1 0 3 2 \leq n \leq 2 \cdot 10^3 2n2103 n n n 为偶数)。

输出描述

针对每个测试用例,输出一个整数,即农场主约翰的农场可以拥有的最少动物数量。

样例输入

3
2
6
8

样例输出

1
2
2

思路

暴力模拟即可,如果是4的倍数就全牛,否则就一个鸡其他全牛。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e6 + 9;
#define int long long
const int MOD = 998244353;
int qmi(int a, int b, int p) {
	int res = 1;
	while (b) {
		if (b & 1) res = res * a % p;
		a = a * a % p;
		b >>= 1;
	}
	return res;
}
int inv(int x) {return qmi(x, MOD - 2, MOD);}

int gcd(int a, int b) {return b > 0 ? gcd(b, a % b) : a;}
int lcm(int a, int b) {return a / gcd(a, b) * b;}

int n, m;
void solve() {
	cin >> n;
    if (n == 2) {
        cout << 1 << "\n";
        return;
    }

    if (n % 4 == 0) cout << n / 4 << '\n';
    else cout << (n - 2) / 4 + 1 << "\n";
}

signed main() {
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int _ = 1;
	cin >> _;
	while (_--) {
		solve();
	}
	return 0;
}

B.Scale

题目大意

蒂娜有一个行数为 n n n 列数为 n n n的正方形网格。网格中的每个单元格要么是 0 0 0
要么是 1 1 1 。蒂娜希望将网格缩小 k k k 倍(** k k k n n n**的除数)。为此,蒂娜将网格分割成 k × k k \times k k×k 个不重叠的单元格块,使得每个单元格正好属于一个单元格块。

然后,蒂娜将每个单元格块替换为与单元格块中单元格值相等的单个单元格。保证同一区块中的每个单元格都具有相同的值

例如,下面的演示显示一个网格被缩小了 3 3 3 倍。

原始

0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0

缩小后

0 0 0 1 1 1
1 1 1 0 0 0

帮助 Tina 将网格缩小 k k k

输入描述

第一行包含一个整数 t t t ( 1 ≤ t ≤ 100 1 \leq t \leq 100 1t100 ) —— 测试用例的数量。

对于每个测试用例:

  • 第一行包含两个整数 n n n k k k ( 1 ≤ n ≤ 1000 1 \leq n \leq 1000 1n1000, 1 ≤ k ≤ n 1 \le k \le n 1kn k k k n n n 的除数) —— 网格的行数和列数,以及蒂娜希望缩小网格的因子。
  • 接下来 n n n 行,每行包含 n n n 个字符( 0 0 0 1 1 1)—— 描述网格单元格的值。

保证每个 k × k k \times k k×k 的网格块都具有相同的值。
保证所有测试用例的 n n n 之和不超过 1000 1000 1000

输出描述

针对每个测试用例,在新的一行输出网格缩小了 k k k 倍的结果。

样例输入

4
4 4
0000
0000
0000
0000
6 3
000111
000111
000111
111000
111000
111000
6 2
001100
001100
111111
111111
110000
110000
8 1
11111111
11111111
11111111
11111111
11111111
11111111
11111111
11111111

样例输出

0
01
10
010
111
100
11111111
11111111
11111111
11111111
11111111
11111111
11111111
11111111

思路

按照要求模拟即可,每次枚举到列:列加k,枚举到行:行加k,用一个cnt记录一下答案的真实行数,每次行加k时,cnt++。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1009;
#define int long long
const int MOD = 998244353;
int qmi(int a, int b, int p) {
	int res = 1;
	while (b) {
		if (b & 1) res = res * a % p;
		a = a * a % p;
		b >>= 1;
	}
	return res;
}
int inv(int x) {return qmi(x, MOD - 2, MOD);}

int gcd(int a, int b) {return b > 0 ? gcd(b, a % b) : a;}
int lcm(int a, int b) {return a / gcd(a, b) * b;}

int n, k;
string s[N], ans[N];
void solve() {
	cin >> n >> k;
    for (int i = 0; i < n; ++ i) 
        s[i].clear(), ans[i].clear();
	for (int i = 0; i < n; ++ i) {
        cin >> s[i];
    }
    int cnt = 0;
    for (int i = 0; i < n; i += k) {
        for (int j = 0; j < n; j += k) {
            ans[cnt] += s[i][j];
            // cout << i << " " << s[i] << "\n";
            // cout << j << " " << s[i][j] << "\n";
        }
        cnt ++;
    }
    for (int i = 0; i < n / k; ++ i) {
        cout << ans[i] << "\n";
    }
}

signed main() {
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int _ = 1;
	cin >> _;
	while (_--) {
		solve();
	}
	return 0;
}

C.Sort

题目大意

给定两个长度为 n n n 的字符串 a a a b b b。然后,您(被迫)回答 q q q 个问题。

对于每个查询,您会得到一个由 l l l r r r 限定的范围。在一次操作中,您可以选择一个整数 i i i ( l ≤ i ≤ r l \leq i \leq r lir ),并设置 a i = x a_i = x ai=x 其中 x x x 是您想要的任何字符。在 sorted(a[l..r]) = sorted(b[l..r]) \texttt{sorted(a[l..r])} = \texttt{sorted(b[l..r])} sorted(a[l..r])=sorted(b[l..r]) 条件下,输出必须执行的最少操作数。**对一个查询执行的操作不会影响其他查询。

对于任意字符串 c c c 来说, sorted(c[l..r]) \texttt{sorted(c[l..r])} sorted(c[l..r]) 表示由按字典序排列的字符 c l , c l + 1 , . . . , c r c_l, c_{l+1}, ..., c_r cl,cl+1,...,cr 组成的子串。

输入描述

第一行包含 t t t ( 1 ≤ t ≤ 1000 1 \leq t \leq 1000 1t1000 ) —— 测试用例的数量。

每个测试用例的第一行包含两个整数 n n n q q q ( 1 ≤ n , q ≤ 2 ⋅ 1 0 5 1 \leq n, q \leq 2 \cdot 10^5 1n,q2105 ) —— 两个字符串的长度和查询次数。

接下来一行包含长度为 n n n 的字符串 a a a。可以保证 a a a 只包含小写拉丁字母。

接下来一行包含长度为 n n n 的字符串 b b b。保证 b b b 只包含小写拉丁字母。

接下来的 q q q 行包含两个整数 l l l r r r ( 1 ≤ l ≤ r ≤ n 1 \leq l \leq r \leq n 1lrn ) —— 查询范围。

保证所有测试用例中 n n n q q q 的总和不超过 2 ⋅ 1 0 5 2 \cdot 10^5 2105

输出描述

对于每个查询,在新行中输出一个整数,即需要执行的最少操作数。

样例输入

3
5 3
abcde
edcba
1 5
1 4
3 3
4 2
zzde
azbe
1 3
1 4
6 3
uwuwuw
wuwuwu
2 4
1 3
1 6

样例输出

0
1
0
2
2
1
1
0

样例说明

对于第一个查询, sorted(a[1..5]) = \texttt{sorted(a[1..5])} = sorted(a[1..5])= abcde 和 sorted(b[1..5]) = \texttt{sorted(b[1..5])} = sorted(b[1..5])= abcde,因此无需进行任何操作。

对于第二个查询,需要设置 a 1 = a_1 = a1= e,然后是 sorted(a[1..4]) = sorted(b[1..4]) = \texttt{sorted(a[1..4])} = \texttt{sorted(b[1..4])} = sorted(a[1..4])=sorted(b[1..4])= bcde。

思路

计算 26 26 26个字母在两个字符串中的数量前缀和,在之后的 l l l r r r之间枚举两个字符串 26 26 26个字母的数量差,如果 a a a数组的一个字母的数量 t 1 t1 t1小于 b b b数组的对应字母的数量 t 2 t2 t2,那么应进行操作 t 2 − t 1 t2 - t1 t2t1,最后结果累加,注意内存不要超限。

#include<iostream>
using namespace std;
#define ll long long
const int N = 2e5 + 9;
string a, b;
int n, m;
int sta[N][30], stb[N][30];
void solve() {
    for (int i = 1; i <= n; ++ i) {
        for (int j = 0; j < 26; ++ j) {
            sta[i][j] = 0;
            stb[i][j] = 0;
        }
    }
    cin >> n >> m;
	cin >> a >> b;
    a = '?' + a;
    b = '?' + b;
    for (int i = 1; i <= n; ++ i) {
        sta[i][a[i] - 'a'] = sta[i - 1][a[i] - 'a'] + 1;
        stb[i][b[i] - 'a'] = stb[i - 1][b[i] - 'a'] + 1;
        for (int j = 0; j < 26; ++ j) {
            if (j != a[i] - 'a') sta[i][j] = sta[i - 1][j];
            if (j != b[i] - 'a') stb[i][j] = stb[i - 1][j];
        }
    }
    while (m --) {
        int l, r; cin >> l >> r;
        int dis = 0;
        for (int i = 0; i < 26; ++ i) {
            int t1 = sta[r][i] - sta[l - 1][i];
            int t2 = stb[r][i] - stb[l - 1][i];
            dis += t1 >= t2 ? t1 - t2 : 0;
        }
        cout << dis << "\n";
    }
}

signed main() {
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int _ = 1;
	cin >> _;
	while (_--) {
		solve();
	}
	return 0;
}

D.Fun

题目大意

给定两个整数 n n n x x x,求满足 a b + a c + b c ≤ n ab + ac + bc \le n ab+ac+bcn a + b + c ≤ x a + b + c \le x a+b+cx正整数三元组 ( a , b , c ) (a, b, c) (a,b,c) 的个数。

注意顺序问题(例如 ( 1 , 1 , 2 ) (1, 1, 2) (1,1,2) ( 1 , 2 , 1 ) (1, 2, 1) (1,2,1) 被视为不同),且 a a a b b b c c c 必须严格大于 0 0 0

输入描述

第一行包含一个整数 t t t ( 1 ≤ t ≤ 1 0 4 1 \leq t \leq 10^4 1t104 ) —— 测试用例的数量。

每个测试用例包含两个整数 n n n x x x ( 1 ≤ n , x ≤ 1 0 6 1 \leq n, x \leq 10^6 1n,x106 )。

保证所有测试用例的 n n n 之和不超过 1 0 6 10^6 106,所有测试用例的 x x x 之和不超过 1 0 6 10^6 106

输出描述

输出一个整数 —— 满足 a b + a c + b c ≤ n ab + ac + bc \le n ab+ac+bcn a + b + c ≤ x a + b + c \le x a+b+cx 的正整数三元组 ( a , b , c ) (a, b, c) (a,b,c) 的个数。

样例输入

4
7 4
10 5
7 1000
900000 400000

样例输出

4
10
7
1768016938

样例说明

在第一个测试用例中,三元组是 ( 1 , 1 , 1 1, 1, 1 1,1,1 )、( 1 , 1 , 2 1, 1, 2 1,1,2 )、( 1 , 2 , 1 1, 2, 1 1,2,1 ) 和 ( 2 , 1 , 1 2, 1, 1 2,1,1 )。

在第二个测试案例中,三元组分别是 ( 1 , 1 , 1 1, 1, 1 1,1,1 )、( 1 , 1 , 2 1, 1, 2 1,1,2 )、( 1 , 1 , 3 1, 1, 3 1,1,3 )、( 1 , 2 , 1 1, 2, 1 1,2,1 )、( 1 , 2 , 2 1, 2, 2 1,2,2 )、( 1 , 3 , 1 1, 3, 1 1,3,1 )、( 2 , 1 , 1 2, 1, 1 2,1,1 )、( 2 , 1 , 2 2, 1, 2 2,1,2 )、( 2 , 2 , 1 2, 2, 1 2,2,1 ) 和 ( 3 , 1 , 1 3, 1, 1 3,1,1 )。

思路

实际上通过剪枝这道题可以暴力去做, a a a b b b都从 1 1 1 x − 2 x-2 x2 a + b > = x a+b>=x a+b>=x时剪掉, a b + c ∗ ( a + b ) < = n ab+c*(a+b)<=n ab+c(a+b)<=n,其中 c > = 1 c>=1 c>=1,所以 a b + a + b > = n ab+a+b>=n ab+a+b>=n时剪掉。剩下的 c c c二分出最大值,小于等于最大值的一定都符合,所以 a n s + = ans+= ans+=最大值。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e6 + 9;
#define int long long
const int MOD = 998244353;
int qmi(int a, int b, int p) {
	int res = 1;
	while (b) {
		if (b & 1) res = res * a % p;
		a = a * a % p;
		b >>= 1;
	}
	return res;
}
int inv(int x) {return qmi(x, MOD - 2, MOD);}

int gcd(int a, int b) {return b > 0 ? gcd(b, a % b) : a;}
int lcm(int a, int b) {return a / gcd(a, b) * b;}

int n, x;
void solve() {
	cin >> n >> x;
    int ans = 0;
    for (int i = 1; i <= x - 2; ++ i) {
        for (int j = 1; j <= x - 2 && i + j <= x; ++ j) {
            if (i * j + i + j > n) break;
            int l = 1, r = x - i - j;
            while(l < r) {
                int mid = l + r + 1 >> 1;
                if (i * j + j * mid + i * mid <= n) l = mid;
                else r = mid - 1;
            }
            ans += r;
        }
    }
    cout << ans << "\n";
}

signed main() {
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int _ = 1;
	cin >> _;
	while (_--) {
		solve();
	}
	return 0;
}
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Codeforces Round 894 (Div. 3) 是一个Codeforces举办的比赛,是第894轮的Div. 3级别比赛。它包含了一系列题目,其中包括题目E. Kolya and Movie Theatre。 根据题目描述,E. Kolya and Movie Theatre问题要求我们给定两个字符串,通过三种操作来让字符串a等于字符串b。这三种操作分别为:交换a中相同位置的字符、交换a中对称位置的字符、交换b中对称位置的字符。我们需要先进行一次预处理,替换a中的字符,然后进行上述三种操作,最终得到a等于b的结果。我们需要计算预处理操作的次数。 根据引用的讨论,当且仅当b[i]==b[n-i-1]时,如果a[i]!=a[n-i-1],需要进行一次操作;否则不需要操作。所以我们可以遍历字符串b的前半部分,判断对应位置的字符是否与后半部分对称,并统计需要进行操作的次数。 以上就是Codeforces Round 894 (Div. 3)的简要说明和题目E. Kolya and Movie Theatre的要求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Codeforces Round #498 (Div. 3) (A+B+C+D+E+F)](https://blog.csdn.net/qq_46030630/article/details/108804114)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Codeforces Round 894 (Div. 3)A~E题解](https://blog.csdn.net/gyeolhada/article/details/132491891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值