240424刷题题解
Walk on Matrix
CodeForces - 1332D
思路
构造题,每个 d p i , j dp_{i,j} dpi,j都是由其左上方向中的按位与最大值决定的。
我们需要从使得贪心解与正确解的差值为 k k k。
为了方便获得 k k k,可以考虑构造一个贪心解为 0 0 0的矩阵。
写出例二的二进制表示
观察可知左边界上的数只能由其上方的数决定(上边界同理)。
由按位与的性质可知, 2 n − 1 2^{n}-1 2n−1即 1111111 … 1111111\ldots 1111111…这种形式的数按位与任意数 x x x得到的数任然是 x x x本身。
利用这两条性质,我们可以利用左边界或者上边界来传递需要的数。
由按位与的性质可知,如果 2 n > x 2^n>x 2n>x,那么 2 n & x = 0 2^n\&x=0 2n&x=0。
利用条性质,我们可以构造出如下矩阵,利用上边界和右边界(或左边界和下边界)以及 2 n + 1 − 1 2^{n+1}-1 2n+1−1传递 k k k,利用 2 n 2^n 2n来截断边界上的正确解。
题解
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <unordered_map>
#include <cstring>
#include <cstdio>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <list>
#include <bitset>
#include <cmath>
#include <numeric>
#define endl '\n'
#define ft first
#define sd second
#define yes cout << "yes\n"
#define no cout << "no\n"
#define Yes cout << "Yes\n"
#define No cout << "No\n"
#define YES cout << "YES\n"
#define NO cout << "NO\n"
#define pb push_back
#define eb emplace_back
#define all(x) x.begin(), x.end()
#define unq_all(x) x.erase(unique(all(x)), x.end())
#define sort_all(x) sort(all(x))
#define reverse_all(x) reverse(all(x))
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f
#define RED cout << "\033[91m"
#define GREEN cout << "\033[92m"
#define YELLOW cout << "\033[93m"
#define BLUE cout << "\033[94m"
#define MAGENTA cout << "\033[95m"
#define CYAN cout << "\033[96m"
#define RESET cout << "\033[0m"
// 红色
#define DEBUG1(x) \
RED; \
cout << #x << " : " << x << endl; \
RESET;
// 绿色
#define DEBUG2(x) \
GREEN; \
cout << #x << " : " << x << endl; \
RESET;
// 蓝色
#define DEBUG3(x) \
BLUE; \
cout << #x << " : " << x << endl; \
RESET;
// 品红
#define DEBUG4(x) \
MAGENTA; \
cout << #x << " : " << x << endl; \
RESET;
// 青色
#define DEBUG5(x) \
CYAN; \
cout << #x << " : " << x << endl; \
RESET;
// 黄色
#define DEBUG6(x) \
YELLOW; \
cout << #x << " : " << x << endl; \
RESET;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<string, string> pss;
typedef pair<string, int> psi;
typedef pair<string, ll> psl;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<string> vs;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<pss> vpss;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef queue<int> qi;
typedef queue<ll> ql;
typedef queue<pii> qpii;
typedef queue<pll> qpll;
typedef queue<psi> qpsi;
typedef queue<psl> qpsl;
typedef priority_queue<int> pqi;
typedef priority_queue<ll> pql;
typedef priority_queue<string> pqs;
typedef priority_queue<pii> pqpii;
typedef priority_queue<psi> pqpsi;
typedef priority_queue<pll> pqpl;
typedef priority_queue<psi> pqpsl;
typedef map<int, int> mii;
typedef map<int, bool> mib;
typedef map<ll, ll> mll;
typedef map<ll, bool> mlb;
typedef map<char, int> mci;
typedef map<char, ll> mcl;
typedef map<char, bool> mcb;
typedef map<string, int> msi;
typedef map<string, ll> msl;
typedef map<int, bool> mib;
typedef unordered_map<int, int> umii;
typedef unordered_map<ll, ll> uml;
typedef unordered_map<char, int> umci;
typedef unordered_map<char, ll> umcl;
typedef unordered_map<string, int> umsi;
typedef unordered_map<string, ll> umsl;
template <typename T>
inline T read()
{
T x = 0;
int y = 1;
char ch = getchar();
while (ch > '9' || ch < '0')
{
if (ch == '-')
y = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
x = (x << 3) + (x << 1) + (ch ^ 48);
ch = getchar();
}
return x * y;
}
template <typename T>
inline void write(T x)
{
if (x < 0)
{
putchar('-');
x = -x;
}
if (x >= 10)
{
write(x / 10);
}
putchar(x % 10 + '0');
}
/*#####################################BEGIN#####################################*/
void solve()
{
int k;
cin >> k;
cout << 3 << " " << 2 << endl;
int t1 = 131072;
int t2 = 262143;
cout << t2 << " " << k << endl;
cout << t1 << " " << t2 << endl;
cout << k << " " << k << endl;
}
int main()
{
ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);
int _ = 1;
// std::cin >> _;
while (_--)
{
solve();
}
return 0;
}
//
Peaceful Rooks
CodeForces - 1411C
图,dfs
思路
仔细思考不难发现,如果以相同行号和列号作为一个节点的编号,那么可以轻易的将点在棋盘上的位置关系转化为图上的边,那么要移动棋子使得棋子的行号和列行相同,则表示为要将我们所建的抽象图的每个点转化为自环。因为同一行和列上不能同时出现两个棋子,即一个点的度数不能大于2。所以如果要把一个环上的所有点的边都变成自环,就需要额外一个点辅助存放拆下来的第一条边,所以需要 n + 1 n+1 n+1次操作,如果把一条链上的所有点的边变成自环,只需 n n n次操作。
所以,
总操作数
=
环上的点数
+
1
+
链上的点数
总操作数=环上的点数+1+链上的点数
总操作数=环上的点数+1+链上的点数
只需要用并查集查一下抽象图上的环就行了。
题解
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <unordered_map>
#include <cstring>
#include <cstdio>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <list>
#include <bitset>
#include <cmath>
#include <numeric>
#define endl '\n'
#define ft first
#define sd second
#define yes cout << "yes\n"
#define no cout << "no\n"
#define Yes cout << "Yes\n"
#define No cout << "No\n"
#define YES cout << "YES\n"
#define NO cout << "NO\n"
#define pb push_back
#define eb emplace_back
#define all(x) x.begin(), x.end()
#define unq_all(x) x.erase(unique(all(x)), x.end())
#define sort_all(x) sort(all(x))
#define reverse_all(x) reverse(all(x))
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f
#define RED cout << "\033[91m"
#define GREEN cout << "\033[92m"
#define YELLOW cout << "\033[93m"
#define BLUE cout << "\033[94m"
#define MAGENTA cout << "\033[95m"
#define CYAN cout << "\033[96m"
#define RESET cout << "\033[0m"
// 红色
#define DEBUG1(x) \
RED; \
cout << #x << " : " << x << endl; \
RESET;
// 绿色
#define DEBUG2(x) \
GREEN; \
cout << #x << " : " << x << endl; \
RESET;
// 蓝色
#define DEBUG3(x) \
BLUE; \
cout << #x << " : " << x << endl; \
RESET;
// 品红
#define DEBUG4(x) \
MAGENTA; \
cout << #x << " : " << x << endl; \
RESET;
// 青色
#define DEBUG5(x) \
CYAN; \
cout << #x << " : " << x << endl; \
RESET;
// 黄色
#define DEBUG6(x) \
YELLOW; \
cout << #x << " : " << x << endl; \
RESET;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<string, string> pss;
typedef pair<string, int> psi;
typedef pair<string, ll> psl;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<string> vs;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<pss> vpss;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef queue<int> qi;
typedef queue<ll> ql;
typedef queue<pii> qpii;
typedef queue<pll> qpll;
typedef queue<psi> qpsi;
typedef queue<psl> qpsl;
typedef priority_queue<int> pqi;
typedef priority_queue<ll> pql;
typedef priority_queue<string> pqs;
typedef priority_queue<pii> pqpii;
typedef priority_queue<psi> pqpsi;
typedef priority_queue<pll> pqpl;
typedef priority_queue<psi> pqpsl;
typedef map<int, int> mii;
typedef map<int, bool> mib;
typedef map<ll, ll> mll;
typedef map<ll, bool> mlb;
typedef map<char, int> mci;
typedef map<char, ll> mcl;
typedef map<char, bool> mcb;
typedef map<string, int> msi;
typedef map<string, ll> msl;
typedef map<int, bool> mib;
typedef unordered_map<int, int> umii;
typedef unordered_map<ll, ll> uml;
typedef unordered_map<char, int> umci;
typedef unordered_map<char, ll> umcl;
typedef unordered_map<string, int> umsi;
typedef unordered_map<string, ll> umsl;
template <typename T>
inline T read()
{
T x = 0;
int y = 1;
char ch = getchar();
while (ch > '9' || ch < '0')
{
if (ch == '-')
y = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
x = (x << 3) + (x << 1) + (ch ^ 48);
ch = getchar();
}
return x * y;
}
template <typename T>
inline void write(T x)
{
if (x < 0)
{
putchar('-');
x = -x;
}
if (x >= 10)
{
write(x / 10);
}
putchar(x % 10 + '0');
}
/*#####################################BEGIN#####################################*/
const int N = 2e5 + 5;
int p[N];
int find(int x)
{
if (p[x] != x)
p[x] = find(p[x]);
return p[x];
}
void solve()
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++)
p[i] = i;
int a, b;
int ans = 0;
for (int i = 0; i < m; i++)
{
cin >> a >> b;
if (a == b)
continue;
if (find(a) == find(b))
ans += 2;
else
{
ans++;
p[find(a)] = find(b);
}
}
cout << ans << endl;
}
int main()
{
ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);
int _ = 1;
std::cin >> _;
while (_--)
{
solve();
}
return 0;
}
// https://codeforces.com/problemset/problem/1411/C
Mathematical Problem
CodeForces - 1916D
思路
对于 n ≤ 3 n\leq3 n≤3来说,答案由样例直接给出了。
所以考虑 n ≥ 5 n\geq5 n≥5的情况。
若 a = b 2 a=b^2 a=b2,则 b × 100 = ( c × 10 ) 2 b\times100=(c\times10)^2 b×100=(c×10)2,所以对于任意 n ≥ 3 n\geq3 n≥3来说,我们都可以由 n − 2 n-2 n−2的方案乘以 100 100 100获得 n − 2 n-2 n−2种方案,所以我们需要只需要 再额外寻找两个方案就行了。
由于 × 100 \times100 ×100使得数集中多了两个 0 0 0,所以需要寻找一种平方数,在非首位插入两个零之后仍为平方数。
观察样例给出的 n n n为 3 3 3的方案: 169 , 196 , 961 169,196,961 169,196,961,尝试插入两个 0 0 0,发现 10609 = 10 3 2 , 90601 = 30 1 2 10609=103^2,90601=301^2 10609=1032,90601=3012。
以此类推,发现 1006009 = 100 3 2 , 9006001 = 300 1 2 1006009=1003^2,9006001=3001^2 1006009=10032,9006001=30012。
所以所需的两个平方数可以通过在 169 169 169和 961 961 961的第 2 2 2位和倒数第 2 2 2位插入 n − 3 2 \frac {n-3}{2} 2n−3个 0 0 0获得。
题解
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <unordered_map>
#include <cstring>
#include <cstdio>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <list>
#include <bitset>
#include <cmath>
#include <numeric>
#define endl '\n'
#define ft first
#define sd second
#define yes cout << "yes\n"
#define no cout << "no\n"
#define Yes cout << "Yes\n"
#define No cout << "No\n"
#define YES cout << "YES\n"
#define NO cout << "NO\n"
#define pb push_back
#define eb emplace_back
#define all(x) x.begin(), x.end()
#define unq_all(x) x.erase(unique(all(x)), x.end())
#define sort_all(x) sort(all(x))
#define reverse_all(x) reverse(all(x))
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f
#define RED cout << "\033[91m"
#define GREEN cout << "\033[92m"
#define YELLOW cout << "\033[93m"
#define BLUE cout << "\033[94m"
#define MAGENTA cout << "\033[95m"
#define CYAN cout << "\033[96m"
#define RESET cout << "\033[0m"
// 红色
#define DEBUG1(x) \
RED; \
cout << #x << " : " << x << endl; \
RESET;
// 绿色
#define DEBUG2(x) \
GREEN; \
cout << #x << " : " << x << endl; \
RESET;
// 蓝色
#define DEBUG3(x) \
BLUE; \
cout << #x << " : " << x << endl; \
RESET;
// 品红
#define DEBUG4(x) \
MAGENTA; \
cout << #x << " : " << x << endl; \
RESET;
// 青色
#define DEBUG5(x) \
CYAN; \
cout << #x << " : " << x << endl; \
RESET;
// 黄色
#define DEBUG6(x) \
YELLOW; \
cout << #x << " : " << x << endl; \
RESET;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<string, string> pss;
typedef pair<string, int> psi;
typedef pair<string, ll> psl;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<string> vs;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<pss> vpss;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef queue<int> qi;
typedef queue<ll> ql;
typedef queue<pii> qpii;
typedef queue<pll> qpll;
typedef queue<psi> qpsi;
typedef queue<psl> qpsl;
typedef priority_queue<int> pqi;
typedef priority_queue<ll> pql;
typedef priority_queue<string> pqs;
typedef priority_queue<pii> pqpii;
typedef priority_queue<psi> pqpsi;
typedef priority_queue<pll> pqpl;
typedef priority_queue<psi> pqpsl;
typedef map<int, int> mii;
typedef map<int, bool> mib;
typedef map<ll, ll> mll;
typedef map<ll, bool> mlb;
typedef map<char, int> mci;
typedef map<char, ll> mcl;
typedef map<char, bool> mcb;
typedef map<string, int> msi;
typedef map<string, ll> msl;
typedef map<int, bool> mib;
typedef unordered_map<int, int> umii;
typedef unordered_map<ll, ll> uml;
typedef unordered_map<char, int> umci;
typedef unordered_map<char, ll> umcl;
typedef unordered_map<string, int> umsi;
typedef unordered_map<string, ll> umsl;
template <typename T>
inline T read()
{
T x = 0;
int y = 1;
char ch = getchar();
while (ch > '9' || ch < '0')
{
if (ch == '-')
y = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
x = (x << 3) + (x << 1) + (ch ^ 48);
ch = getchar();
}
return x * y;
}
template <typename T>
inline void write(T x)
{
if (x < 0)
{
putchar('-');
x = -x;
}
if (x >= 10)
{
write(x / 10);
}
putchar(x % 10 + '0');
}
/*#####################################BEGIN#####################################*/
const int N = 105;
vs ans[N];
void solve()
{
int n;
cin >> n;
for (auto an : ans[n])
{
cout << an << endl;
}
}
int main()
{
ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);
int _ = 1;
std::cin >> _;
ans[1].eb("1");
ans[3].eb("169");
ans[3].eb("196");
ans[3].eb("961");
for (int i = 5; i <= 99; i += 2)
{
for (auto j : ans[i - 2])
{
ans[i].eb(j + "00");
}
int len = (i - 3) / 2;
string s1 = "1";
string s2 = "9";
for (int j = 0; j < len; j++)
{
s1 += "0";
s2 += "0";
}
s1 += "6";
s2 += "6";
for (int j = 0; j < len; j++)
{
s1 += "0";
s2 += "0";
}
s1 += "9";
s2 += "1";
ans[i].eb(s1);
ans[i].eb(s2);
}
while (_--)
{
solve();
}
return 0;
}
//
Pekora and Trampoline
CodeForces - 1491C
思路
对于 s i s_i si来说,需要经过的轮数,为 s i − f ( s i ) s_i-f(s_i) si−f(si), f ( s i ) f(s_i) f(si)表示 j + s j = i , j ≤ i j+s_j =i,j\leq i j+sj=i,j≤i,即 s i s_{i} si之前会经过 s i s_{i} si的蹦床。
为了尽可能经过尽量多的蹦床,要尽量从编号小的蹦床开始新的一轮。所以从 i = 1 i=1 i=1开始遍历,如果 s i ≠ 1 s_{i}\neq1 si=1,那么对于所有的 i + 2 ∼ i + s i i+2\sim i+s_{i} i+2∼i+si都会被经过,如果当 s i = 1 s_{i}=1 si=1时这个点被经过,那么 s i + 1 s_{i+1} si+1也会受影响。
题解
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <unordered_map>
#include <cstring>
#include <cstdio>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <list>
#include <bitset>
#include <cmath>
#include <numeric>
#define endl '\n'
#define ft first
#define sd second
#define yes cout << "yes\n"
#define no cout << "no\n"
#define Yes cout << "Yes\n"
#define No cout << "No\n"
#define YES cout << "YES\n"
#define NO cout << "NO\n"
#define pb push_back
#define eb emplace_back
#define all(x) x.begin(), x.end()
#define unq_all(x) x.erase(unique(all(x)), x.end())
#define sort_all(x) sort(all(x))
#define reverse_all(x) reverse(all(x))
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f
#define RED cout << "\033[91m"
#define GREEN cout << "\033[92m"
#define YELLOW cout << "\033[93m"
#define BLUE cout << "\033[94m"
#define MAGENTA cout << "\033[95m"
#define CYAN cout << "\033[96m"
#define RESET cout << "\033[0m"
// 红色
#define DEBUG1(x) \
RED; \
cout << #x << " : " << x << endl; \
RESET;
// 绿色
#define DEBUG2(x) \
GREEN; \
cout << #x << " : " << x << endl; \
RESET;
// 蓝色
#define DEBUG3(x) \
BLUE; \
cout << #x << " : " << x << endl; \
RESET;
// 品红
#define DEBUG4(x) \
MAGENTA; \
cout << #x << " : " << x << endl; \
RESET;
// 青色
#define DEBUG5(x) \
CYAN; \
cout << #x << " : " << x << endl; \
RESET;
// 黄色
#define DEBUG6(x) \
YELLOW; \
cout << #x << " : " << x << endl; \
RESET;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<string, string> pss;
typedef pair<string, int> psi;
typedef pair<string, ll> psl;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<string> vs;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
typedef vector<pss> vpss;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef queue<int> qi;
typedef queue<ll> ql;
typedef queue<pii> qpii;
typedef queue<pll> qpll;
typedef queue<psi> qpsi;
typedef queue<psl> qpsl;
typedef priority_queue<int> pqi;
typedef priority_queue<ll> pql;
typedef priority_queue<string> pqs;
typedef priority_queue<pii> pqpii;
typedef priority_queue<psi> pqpsi;
typedef priority_queue<pll> pqpl;
typedef priority_queue<psi> pqpsl;
typedef map<int, int> mii;
typedef map<int, bool> mib;
typedef map<ll, ll> mll;
typedef map<ll, bool> mlb;
typedef map<char, int> mci;
typedef map<char, ll> mcl;
typedef map<char, bool> mcb;
typedef map<string, int> msi;
typedef map<string, ll> msl;
typedef map<int, bool> mib;
typedef unordered_map<int, int> umii;
typedef unordered_map<ll, ll> uml;
typedef unordered_map<char, int> umci;
typedef unordered_map<char, ll> umcl;
typedef unordered_map<string, int> umsi;
typedef unordered_map<string, ll> umsl;
template <typename T>
inline T read()
{
T x = 0;
int y = 1;
char ch = getchar();
while (ch > '9' || ch < '0')
{
if (ch == '-')
y = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
x = (x << 3) + (x << 1) + (ch ^ 48);
ch = getchar();
}
return x * y;
}
template <typename T>
inline void write(T x)
{
if (x < 0)
{
putchar('-');
x = -x;
}
if (x >= 10)
{
write(x / 10);
}
putchar(x % 10 + '0');
}
/*#####################################BEGIN#####################################*/
void solve()
{
int n;
cin >> n;
vl s(n + 5);
for (int i = 1; i <= n; i++)
{
cin >> s[i];
}
vl fs(n + 5); // 储存之前被经过的轮数
ll ans = 0;
for (int i = 1; i <= n; i++)
{
for (int j = i + 2; j <= n && j <= i + s[i]; j++)
{
fs[j]++;
}
fs[i + 1] += max(0LL, fs[i] - s[i] + 1);
ans += max(0LL, s[i] - fs[i] - 1);
}
cout << ans << endl;
}
int main()
{
ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);
int _ = 1;
std::cin >> _;
while (_--)
{
solve();
}
return 0;
}
// https://codeforces.com/problemset/problem/1491/C