A

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long; bool solve() {
int n;
cin >> n;
int mx = -2e9, mi = 2e9;
for (int i = 1;i <= n;i++) {
int x;
cin >> x;
mi = min(x, mi);
mx = max(x, mx);
}
if (mi < 0) cout << mi << '\n';
else cout << mx << '\n';
return true;
} int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}

B

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long; bool solve() {
int n;
cin >> n;
int pos[3];
for (int i = 1;i <= n;i++) {
int x;
cin >> x;
if (x == 1) pos[0] = i;
else if (x == 2) pos[1] = i;
else if (x == n) pos[2] = i;
}
if (pos[2] < pos[1] && pos[2] < pos[0]) cout << pos[2] << ' ' << min(pos[0], pos[1]) << '\n';
else if (pos[2] > pos[1] && pos[2] > pos[0]) cout << pos[2] << ' ' << max(pos[0], pos[1]) << '\n';
else cout << 1 << ' ' << 1 << '\n';
return true;
} int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}

C

题目

构造一个 \(n \times m\) 的矩阵,矩阵中的元素是 \(1 \sim n \times m\) 的数字,每个数字只能出现一次,要求相邻元素差的绝对值不是个素数。

题解

知识点:构造。

方法一

按 \(m\) 奇偶性分类:

  1. \(m\) 是偶数,可构造形如:

    \[\begin{array}{l}
    &1 &2 &3 &4\\
    &5 &6 &7 &8\\
    &9 &10 &11 &12\\
    &13 &14 &15 &16\\
    \end{array}
    \]

    可以保证左右的差的绝对值为 \(1\) ,上下的差的绝对值是 \(m\) 。

  2. \(m\) 是奇数,可构造形如:

    \[\begin{array}{l}
    &1 &2 &3 &4 &5\\
    &7 &8 &9 &10 &6\\
    &13 &14 &15 &11 &12\\
    &19 &20 &16 &17 &18\\
    \end{array}
    \]

    可以保证左右的差的绝对值为 \(1\) ,上下的差的绝对值是 \(m+1\) 。

时间复杂度 \(O(nm)\)

空间复杂度 \(O(1)\)

方法二

可构造形如:

\[\begin{array}{l}
&1 &2 &3 &4\\
&9 &10 &11 &12\\
&17 &18 &19 &20\\
&5 &6 &7 &8\\
&13 &14 &15 &16\\
\end{array}
\]

可以保证左右的差的绝对值为 \(1\) ,上下的差的绝对值是 \(2m\) 或 \(\left( 2 \left\lfloor \dfrac{n-1}{2} \right\rfloor - 1 \right) m\) 。

特别地,当 \(n = 4\) 且 \(m\) 是素数时无法满足,因此考虑 \(n=4\) 时特判,构造形如:

\[\begin{array}{l}
&1 &5 &9 &13 &17\\
&2 &6 &10 &14 &18\\
&3 &7 &11 &15 &19\\
&4 &8 &12 &16 &20\\
\end{array}
\]

时间复杂度 \(O(nm)\)

空间复杂度 \(O(1)\)

代码

方法一

#include <bits/stdc++.h>
using namespace std;
using ll = long long; bool solve() {
int n, m;
cin >> n >> m;
if (m & 1) {
for (int i = 1;i <= n;i++)
for (int j = 1;j <= m;j++)
cout << (i - 1) * m + (j + i - 2) % m + 1 << " \n"[j == m];
}
else {
for (int i = 1;i <= n;i++)
for (int j = 1;j <= m;j++)
cout << (i - 1) * m + j << " \n"[j == m];
}
return true;
} int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}

方法二

#include <bits/stdc++.h>
using namespace std;
using ll = long long; bool solve() {
int n, m;
cin >> n >> m;
if (n == 4) {
for (int i = 1;i <= n;i++)
for (int j = 1;j <= m;j++)
cout << i + (j - 1) * n << " \n"[j == m];
}
else {
for (int i = 1;i <= n;i++) {
int ii = i <= (n + 1) / 2 ? 2 * i - 1 : 2 * (i - (n + 1) / 2);
for (int j = 1;j <= m;j++) {
cout << (ii - 1) * m + j << " \n"[j == m];
}
}
}
return true;
} int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}

D

题目

给定一个只包含 () 两种字符的字符串 \(s\) 。

现在要求从 \(s_1\) 出发,最终到达 \(s_n\) ,每次可以左右移动一个位置,并依次写下到达的位置的字符。

问通过 \(s\) ,最后能否写下一个合法括号序列。

题解

知识点:STL,贪心。

首先若 \(n\) 是奇数无解。

这道题本质就是判断:

  1. 对于最后一个 (( ,其右方是否存在一个 ))
  2. 对于第一个 )) ,其左方是否存在一个 ((

特别地,对于 \(s_1\) 为 ) 或 \(s_n\) 为 ( ,也要认为是 ))((

容易证明,若不满足两个条件的任意一个,那么一定无解;满足这两个条件,一定能构造出一个解。

到这里,其实用两个 set 分别维护 (()) 的位置,可以直接写了:

  1. (()) 都不存在,那么有解。
  2. 若情况1或2满足任意一个,那么无解。
  3. 否则有解。

不过,接下来官方题解的做法更加简洁。

考虑用 set 记录所有位置 \(i\) ,满足:

  1. 若 \(i\) 是奇数,满足 \(s_i\) 是 )
  2. 若 \(i\) 是偶数,满足 \(s_i\) 是 (

可以看到,第一个满足情况1的位置,只可能在 \(s_1\) 或第一个 )) 的位置;最后一个满足情况2的位置,只可能在 \(s_n\) 或最后一个 (( 的位置。

因此,我们可以通过类似的判断:

  1. 若没有位置满足,那么有解。
  2. 若第一个记录的位置是奇数或最后一个记录的位置是偶数,那么无解。
  3. 否则有解。

时间复杂度 \(O((n+q) \log n)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long; int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n, q;
cin >> n >> q;
set<int> st;
for (int i = 1;i <= n;i++) {
char ch;
cin >> ch;
if (ch == '(' && !(i & 1) || ch == ')' && (i & 1)) st.insert(i);
} while (q--) {
int x;
cin >> x;
if (auto it = st.find(x);it != st.end()) st.erase(it);
else st.insert(x);
if (n & 1) {
cout << "NO" << '\n';
continue;
}
if (!st.size()) cout << "YES" << '\n';
else if ((*st.begin() & 1) || !(*prev(st.end()) & 1)) cout << "NO" << '\n';
else cout << "YES" << '\n';
}
return 0;
}

E

题目

给定 \(n,m,k\) ,再给一个长度为 \(n\) 的整数数组 \(a\) 满足 \(a_i \in [1,k]\) 。

求有多少不同的长度为 \(m\) 的整数数组 \(b\) ,满足 \(b_i \in [1,k]\) 且 \(a\) 是 \(b\) 的子序列。

不同的定义:两个数组任意一个位置数字不同,可看做不同。

题解

知识点:线性dp,排列组合。

先考虑朴素的dp。

设 \(f_{i,j}\) 表示考虑了 \(b\) 前 \(i\) 个数字,且作为 \(b\) 的子序列的 \(a\) 的前缀的最长长度为 \(j\) ,有转移方程:

\[f_{i,j} = \begin{cases}
f_{i-1,j-1} + (k-1)f_{i-1,j} &,j < n\\
f_{i-1,j-1} + kf_{i-1,j} &,j = n\\
\end{cases}
\]

显然dp是会超时的,但是我们从中可以发现,整个过程和 \(a\) 一点关系都没。

因此,我们就假设 \(a_i = 1\) ,显然求不满足的比较容易。 \(b\) 共有 \(k^m\) 种,不满足的情况为 \(<n\) 个 \(1\) 且其他都不为 \(1\) ,因此不满足的情况有 $\displaystyle $ 种,所以最终答案为:

\[ k^m -\sum_{i=0}^{n-1} \binom{m}{i}(k-1)^{m-i}
\]

其中组合数是 \(m\) 是 \(10^9\) 的,因此不可以用公式法预处理阶乘及其逆元,考虑用乘法公式递推:

\[\binom{m}{i} = \frac{m-i+1}{i} \binom{m}{i-1}
\]

时间复杂度 \(O(n \log m)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long; const int P = 1e9 + 7;
namespace Number_Theory {
int qpow(int a, ll k) {
int ans = 1;
while (k) {
if (k & 1) ans = 1LL * ans * a % P;
k >>= 1;
a = 1LL * a * a % P;
}
return ans;
}
}
namespace CNM {
using namespace Number_Theory;
const int N = 2e5 + 7;
int n, m, cn[N];
void init(int _n, int _m) {
n = _n;
m = _m;
cn[0] = 1;
for (int i = 1;i <= m;i++) cn[i] = 1LL * (n - i + 1) * qpow(i, P - 2) % P * cn[i - 1] % P;
}
int Cn(int m) {
if (n == m && m == -1) return 1;
if (n < m || m < 0) return 0;
return cn[m];
}
}
using Number_Theory::qpow;
using CNM::Cn; bool solve() {
int n, m, k;
cin >> n >> m >> k;
for (int i = 1, x;i <= n;i++) cin >> x;
CNM::init(m, n);
int ans = qpow(k, m);
for (int i = 0;i <= n - 1;i++) (ans -= 1LL * Cn(i) * qpow(k - 1, m - i) % P - P) %= P;
cout << ans << '\n';
return true;
} int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}

Codeforces Round #877 (Div. 2) A-E的更多相关文章

  1. Codeforces Round #877 (Div. 2) E. Danil and a Part-time Job

    E. Danil and a Part-time Job 题目链接:http://codeforces.com/contest/877/problem/E time limit per test2 s ...

  2. Codeforces Round #877 (Div. 2) D. Olya and Energy Drinks

    题目链接:http://codeforces.com/contest/877/problem/D D. Olya and Energy Drinks time limit per test2 seco ...

  3. Codeforces Round #877 (Div. 2) B. - Nikita and string

    题目链接:http://codeforces.com/contest/877/problem/B Nikita and string time limit per test2 seconds memo ...

  4. Codeforces Round #366 (Div. 2) ABC

    Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...

  5. Codeforces Round #354 (Div. 2) ABCD

    Codeforces Round #354 (Div. 2) Problems     # Name     A Nicholas and Permutation standard input/out ...

  6. Codeforces Round #368 (Div. 2)

    直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...

  7. cf之路,1,Codeforces Round #345 (Div. 2)

     cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅.....   ...

  8. Codeforces Round #279 (Div. 2) ABCDE

    Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems     # Name     A Team Olympiad standard input/outpu ...

  9. Codeforces Round #262 (Div. 2) 1003

    Codeforces Round #262 (Div. 2) 1003 C. Present time limit per test 2 seconds memory limit per test 2 ...

  10. Codeforces Round #262 (Div. 2) 1004

    Codeforces Round #262 (Div. 2) 1004 D. Little Victor and Set time limit per test 1 second memory lim ...

随机推荐

  1. bat基本操作

    一.制作.bat文件:如:新建一个文本文件(.txt)--打开该文件,文件->另存为test.bat,编码为ANSI(支持中文编码): 二.常用写法: 1.输出使用echo:如:echo 文字: ...

  2. [Spring MVC]@RequestMapping 与 @RequestMapping+@RequestResponse的区别

    假定:返回格式均为JSON,JSON实体对象myJson的属性有:data.message.code.status. 二者的区别在于: @RequestMapping:会在最外层包裹 data属性,将 ...

  3. pandas技巧

    1. 计算月初.2022-05-03 得到2022-05-01 df['month']=df['purchase_date'].apply(lambda x : x.replace(day=1))

  4. git撤销某一次commit提交

    一.使用git rebase命令 如果您想彻底删除 Git 中的某次提交的内容,可以使用 git rebase 命令并将该提交删除. 以下是删除 Git 提交内容的步骤: 找到要删除的提交的哈希值.可 ...

  5. Mysql8.0为什么取消了缓存查询的功能

    首先我们介绍一下MySQL的缓存机制 [MySQL缓存机制]简单的说就是缓存sql文本及查询结果,如果运行完全相同的SQL,服务器直接从缓存中取到结果,而不需要再去解析和执行SQL. 但如果表中任何数 ...

  6. 「学习笔记」重修 FHQ-treap

    无旋 treap 的操作方式使得它天生支持维护序列.可持久化等特性. 无旋 treap 又称分裂合并 treap.它仅有两种核心操作,即为 分裂 与 合并.通过这两种操作,在很多情况下可以比旋转 tr ...

  7. 【原型设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

    简介 原型模式(Prototype Pattern)是一种创建型设计模式,使你能够复制已有对象,而无需使代码依赖它们所属的类,同时又能保证性能. 这种模式是实现了一个原型接口,该接口用于创建当前对象的 ...

  8. 「学习笔记」2-SAT问题

    SAT 是适定性 (Satisfiability) 问题的简称.一般形式为 k - 适定性问题,简称 k-SAT.而当 \(k>2\) 时该问题为 NP 完全的.所以我们只研究 \(k=2\) ...

  9. fiddler简单使用

    fiddler简单使用 下载 网上找资源下载 安装 一路同意就可以了 使用 1.配置https证书 这些项全选,然后信任证书,就可以抓到ssl的包 2.改变网络端口 3.改写网页代码 以爬虫网为例,先 ...

  10. 各种远程工具通过ssh连接服务器

    开头 最近遇到一个新的连接方式,不能使用日常的本地通过账号连接,要通过私钥和公钥的连接方式,然后连接到服务器之后才能连接到数据库.因为之前没试过这种连接方式,所以很多工具有不同的连接方式.所以现在就记 ...