$CF\ 639\ (Div\ 2)$
\(CF\ 639\ (Div2)\)
\(A.\)
判断给定拼图是否可拼
找规律发现,只有 \(1\times m,\ n\times 1,\ 2\times 2\) 的可行
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <math.h>
#include <algorithm>
#include <vector>
#define fi first
#define se second
#define pii pair<int, int>
#define pb push_back
#define arrayDebug(a, l, r) for(int i = l; i <= r; ++i) printf("%d%c", a[i], " \n"[i == r])
typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int DX[] = {0, -1, 0, 1, 0, -1, -1, 1, 1};
const int DY[] = {0, 0, 1, 0, -1, -1, 1, 1, -1};
const int MOD = 1e9;
const int N = 5e5 + 7;
const double PI = acos(-1);
const double EPS = 1e-6;
using namespace std;
inline int read()
{
char c = getchar();
int ans = 0, f = 1;
while(!isdigit(c)) {if(c == '-') f = -1; c = getchar();}
while(isdigit(c)) {ans = ans * 10 + c - '0'; c = getchar();}
return ans * f;
}
int t;
int main()
{
t = read();
while(t--) {
int n = read(), m = read();
if(n == 1 || m == 1 || m == 2 && n == 2) puts("YES");
else puts("NO");
}
return 0;
}
/*
5 5
1 2
2 5
5 4
4 3
3 1
*/
\(B.\)
给定高度为 \(h\) 的卡堆的堆积方式以及 \(n\) 张卡片,优先建造高度最高的卡堆,计算可构造的卡堆的最大数量
设 \(dp[i]\) 表示高度为 \(i\) 的卡堆所需卡片数量,找规律发现
预处理各个卡堆所需要的卡片数量,对于当前的 \(n\),不断二分查找可构造的最大卡堆即可
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <math.h>
#include <algorithm>
#include <vector>
#define fi first
#define se second
#define pii pair<int, int>
#define pb push_back
#define arrayDebug(a, l, r) for(int i = l; i <= r; ++i) printf("%d%c", a[i], " \n"[i == r])
typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int DX[] = {0, -1, 0, 1, 0, -1, -1, 1, 1};
const int DY[] = {0, 0, 1, 0, -1, -1, 1, 1, -1};
const int MOD = 1e9;
const int N = 1e5 + 7;
const double PI = acos(-1);
const double EPS = 1e-6;
using namespace std;
inline int read()
{
char c = getchar();
int ans = 0, f = 1;
while(!isdigit(c)) {if(c == '-') f = -1; c = getchar();}
while(isdigit(c)) {ans = ans * 10 + c - '0'; c = getchar();}
return ans * f;
}
int t;
LL dp[N];
int main()
{
dp[1] = 2;
int cnt = 0;
for(int i = 2; i <= N; ++i) {
cnt++, dp[i] = dp[i - 1] + 3 * i - 1;
if(dp[i] >= 1000000000) break;
}
//for(int i = 1; i <= cnt; ++i) dp[i] += dp[i - 1];
t = read();
while(t--) {
int n = read();
int ans = 0;
while(n) {
int p = upper_bound(dp + 1, dp + 1 + cnt, n) - dp;
p--;
if(p > 0 && dp[p] <= n) ans++, n -= dp[p];
else break;
}
printf("%d\n", ans);
}
return 0;
}
/*
5
3
14
15
24
1
*/
\(C.\)
有无限个房间,每个房间对应唯一一个数字,每个房间初始有一个客人
给定长为 \(n\) 的整数序列 \(a\)
现在移动客人,将 \(k\) 房间内的客人移动到房间 \(k + a_{k\ mod\ n}\),询问移动后是否仍然满足每个房间至多只有 \(1\) 个客人
假设 \(a_{k\ mod\ n} = a_{0}\),当然也可以等于其他位置
考虑移动的映射关系
\(k\rightarrow k + a_{k\ mod\ n} = k + a_{0}\)
\(k + 1\rightarrow k + 1 + a_{(k + 1)\ mod\ n} = k + 1 + a_{1}\)
\(k + 2\rightarrow k + 2 + a_{(k + 2)\ mod\ n} = k + 2 + a_{2}\)
\(...\)
\(k + n - 1\rightarrow k + n - 1 + a_{(k + n - 1)\ mod\ n} = k + n - 1 + a_{n - 1}\)
\(k + n\rightarrow k + n + a_{(k + n)\ mod\ n} = k + n + a_{0}\)
分析得到,只需要 \(i + a[i],\ i = 0,\ 1,\ ...,\ n - 1\) 构成模 \(n\) 的一个最小非负完全剩余系即可
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int, int>
#define pb push_back
#define arrayDebug(a, l, r) for(int i = l; i <= r; ++i) printf("%d%c", a[i], " \n"[i == r])
typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int DX[] = {0, -1, 0, 1, 0, -1, -1, 1, 1};
const int DY[] = {0, 0, 1, 0, -1, -1, 1, 1, -1};
const int MOD = 1e9;
const int N = 2e5 + 7;
const double PI = acos(-1);
const double EPS = 1e-6;
using namespace std;
inline int read()
{
char c = getchar();
int ans = 0, f = 1;
while(!isdigit(c)) {if(c == '-') f = -1; c = getchar();}
while(isdigit(c)) {ans = ans * 10 + c - '0'; c = getchar();}
return ans * f;
}
int t;
LL n, a[N];
int main()
{
t = read();
while(t--) {
n = read();
for(int i = 0; i < n; ++i) scanf("%lld", &a[i]);
set<LL> st;
for(int i = 0; i < n; ++i) {
st.insert(((a[i] + i) % n + n) % n);
}
if(st.size() == n) puts("YES");
else puts("NO");
}
return 0;
}
/*
5
3
14
15
24
1
*/
这题想通了还是挺有意思的 😄