提交 bd87bb4a 编写于 作者: 每日一练社区's avatar 每日一练社区

delete md.md file

上级 9618ce64
# k倍区间
**问题描述**
给定一个长度为N的数列,A<sub>1</sub>, A<sub>2</sub>, … A<sub>N</sub>,如果其中一段连续的子序列A<sub>i</sub>, A<sub>i+1</sub>, … A<sub>j</sub>(i <= j)之和是K的倍数,我们就称这个区间[i, j]是K倍区间。
你能求出数列中总共有多少个K倍区间吗?
**输入格式**
第一行包含两个整数N和K。(1 <= N, K <= 100000)
以下N行每行包含一个整数A<sub>i</sub>。(1 <= A<sub>i</sub> <= 100000)
**输出格式**
输出一个整数,代表K倍区间的数目。
**样例输入**
```
5 2
1
2
3
4
5
```
**样例输出**
```
6
```
以下程序实现了该功能,请你补全空白处代码:
```c
#include <bits/stdc++.h>
using namespace std;
int main()
{
long long n, k, ans = 0, son[100000], sum[100000], b[100000] = {0};
cin >> n >> k;
for (int i = 0; i < n; i++)
{
cin >> son[i];
if (i != 0)
__________________
else
sum[i] = son[i] % k;
b[sum[i]]++;
ans += b[sum[i]] - 1;
if (sum[i] == 0)
ans++;
}
cout << ans;
return 0;
}
```
## 答案
```c
sum[i] = (sum[i - 1] + son[i]) % k;
```
## 选项
### A
```c
sum[i] = (sum[i] + son[i]) % k;
```
### B
```c
sum[i] = (sum[i - 1] + son[i]) % k - 1;
```
### C
```c
sum[i] = (sum[i - 1] + son[i - 1]) % k;
```
# 平面切分
**问题描述**
平面上有 N条直线,其中第 i条直线是 y = A<sub>i</sub>*x + B<sub>i</sub>
请计算这些直线将平面分成了几个部分。
**输入格式**
第一行包含一个整数N。
以下N行,每行包含两个整数 A<sub>i</sub>, B<sub>i</sub>
**输出格式**
一个整数代表答案。
**样例输入**
```
3
1 1
2 2
3 3
```
**样例输出**
```
6
```
以下程序实现了这一功能,请你补全空白处的内容:
```c
#include <bits/stdc++.h>
using namespace std;
long double s[1010][2];
long long ans;
bool st[1010];
pair<long double, long double> p;
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> s[i][0] >> s[i][1];
set<pair<long double, long double>> points;
for (int j = 0; j < i; j++)
{
if (st[j])
continue;
if (s[i][0] == s[j][0])
{
if (s[i][1] == s[j][1])
{
st[i] = true;
break;
}
else
continue;
}
__________________
p.second = s[i][0] * p.first + s[i][1];
points.insert(p);
}
if (!st[i])
ans += points.size() + 1;
}
cout << ans + 1;
return 0;
}
```
## 答案
```c
p.first = (s[j][1] - s[i][1]) / (s[i][0] - s[j][0]);
```
## 选项
### A
```c
p.first = (s[j][1] - s[i][1]) / (s[i][1] - s[j][1]);
```
### B
```c
p.first = (s[j][0] - s[i][0]) / (s[i][0] - s[j][0]);
```
### C
```c
p.first = (s[j][0] - s[i][0]) / (s[i][1] - s[j][1]);
```
# 逆波兰表达式
正常的表达式称为中缀表达式,运算符在中间,主要是给人阅读的,机器求解并不方便。
例如:3 + 5 * (2 + 6) - 1
而且,常常需要用括号来改变运算次序。
相反,如果使用逆波兰表达式(前缀表达式)表示,上面的算式则表示为:
```
- + 3 * 5 + 2 6 1
```
不再需要括号,机器可以用递归的方法很方便地求解。
为了简便,我们假设:
1. 只有 + - * 三种运算符
2. 每个运算数都是一个小于10的非负整数
下面的程序对一个逆波兰表示串进行求值。
其返回值为一个数组:其中第一元素表示求值结果,第二个元素表示它已解析的字符数。
请你补全代码:
```c
#include <bits/stdc++.h>
using namespace std;
struct EV
{
int result;
int n;
};
struct EV evaluate(char *x)
{
struct EV ev = {0, 0};
struct EV v1;
struct EV v2;
if (*x == 0)
return ev;
if (x[0] >= '0' && x[0] <= '9')
{
ev.result = x[0] - '0';
ev.n = 1;
return ev;
}
v1 = evaluate(x + 1);
__________________
if (x[0] == '+')
ev.result = v1.result + v2.result;
if (x[0] == '*')
ev.result = v1.result * v2.result;
if (x[0] == '-')
ev.result = v1.result - v2.result;
ev.n = 1 + v1.n + v2.n;
return ev;
}
int main(int argc, char **argv)
{
string str = "-+3*5+261";
const EV &ev = evaluate((char *)(str.c_str()));
cout << ev.result << endl;
return 0;
}
```
## 答案
```c
v2 = evaluate(x + v1.n + 1);
```
## 选项
### A
```c
v2 = evaluate(x + v1.n);
```
### B
```c
v2 = evaluate(v1.n);
```
### C
```c
v2 = evaluate(v1.n + 1);
```
# 灵能传输
**题目背景**
在游戏《星际争霸 II》中,高阶圣堂武士作为星灵的重要 AOE 单位,在游戏的中后期发挥着重要的作用,其技能”灵能风暴“可以消耗大量的灵能对一片区域内的敌军造成毁灭性的伤害。经常用于对抗人类的生化部队和虫族的刺蛇飞龙等低血量单位。
**问题描述**
你控制着 n 名高阶圣堂武士,方便起见标为 1,2,··· ,n。每名高阶圣堂武士需要一定的灵能来战斗,每个人有一个灵能值a<sub>i</sub>表示其拥有的灵能的多少(a<sub>i</sub>非负表示这名高阶圣堂武士比在最佳状态下多余了a<sub>i</sub>点灵能,a<sub>i</sub>为负则表示这名高阶圣堂武士还需要-a<sub>i</sub>点灵能才能到达最佳战斗状态) 。现在系统赋予了你的高阶圣堂武士一个能力,传递灵能,每次你可以选择一个 i ∈ [2,n − 1],若a<sub>i</sub> ≥ 0 则其两旁的高阶圣堂武士,也就是 i − 1、i + 1 这两名高阶圣堂武士会从i 这名高阶圣堂武士这里各抽取 a<sub>i</sub> 点灵能;若 a<sub>i</sub> < 0 则其两旁的高阶圣堂武士也就是 i−1,i+1 这两名高阶圣堂武士会给 i 这名高阶圣堂武士 a<sub>i</sub> 点灵能。形式化来讲就是 a<sub>i-1</sub> + = a<sub>i</sub> ,a<sub>i+1</sub> + = a<sub>i</sub> ,a<sub>i</sub> − = 2a<sub>i</sub>
灵能是非常高效的作战工具,同时也非常危险且不稳定,一位高阶圣堂武士拥有的灵能过多或者过少都不好,定义一组高阶圣堂武士的不稳定度为max<sup>n</sup><sub>i=1</sub> |a<sub>i</sub>|,请你通过不限次数的传递灵能操作使得你控制的这一组高阶圣堂武士的不稳定度最小。
**输入格式**
本题包含多组询问。输入的第一行包含一个正整数 T 表示询问组数。
接下来依次输入每一组询问。
每组询问的第一行包含一个正整数 n,表示高阶圣堂武士的数量。
接下来一行包含 n 个数 a<sub>1</sub> ,a<sub>2</sub> ,··· ,a<sub>n</sub>
**输出格式**
输出 T 行。每行一个整数依次表示每组询问的答案。
**样例输入**
```
3
3
5 -2 3
4
0 0 0 0
3
1 2 3
```
**样例输出**
```
3
0
3
```
**样例说明**
```
对于第一组询问:
对 2 号高阶圣堂武士进行传输操作后 a 1 = 3,a 2 = 2,a 3 = 1。答案为 3。
对于第二组询问:
这一组高阶圣堂武士拥有的灵能都正好可以让他们达到最佳战斗状态。
```
**样例输入**
```
3
4
-1 -2 -3 7
4
2 3 4 -8
5
-1 -1 6 -1 -1
```
**样例输出**
```
5
7
4
```
以下选项<span style="color:red">错误</span>的是?
## aop
### before
```c
#include <bits/stdc++.h>
using namespace std;
```
### after
```c
```
## 答案
```c
typedef long long ll;
#define int ll
#define rep(i, a, n) for (int i = a; i < (int)n; i++)
#define per(i, a, n) for (int i = (int)n - 1; i >= a; i--)
const int maxn = 3e5 + 10;
inline int read()
{
int x = 0, f = 1;
char ch = getchar();
while (!isdigit(ch))
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (isdigit(ch))
{
x = (x << 3) + (x << 1) + ch - 48;
ch = getchar();
}
return x * f;
}
int s[maxn], a[maxn];
bool vis[maxn];
inline void cf()
{
int t = read();
while (t--)
{
int n = read();
s[0] = 0;
rep(i, 1, n + 1)
{
int x = read();
s[i] = s[i + 1] + x;
}
int s0 = 0, sn = s[n];
if (s0 > sn)
swap(s0, sn);
sort(s, s + n + 1);
rep(i, 0, n + 1) if (s[i] == s0)
{
s0 = i;
break;
}
per(i, 0, n + 1) if (s[i] == sn)
{
sn = i;
break;
}
int l = 0, r = n;
rep(i, 0, n + 1) vis[i] = 0;
for (int i = s0; i >= 0; i -= 2)
a[l++] = s[i], vis[i] = 1;
for (int i = sn; i <= n; i += 2)
a[r--] = s[i], vis[i] = 1;
rep(i, 0, n + 1) if (!vis[i]) a[l++] = s[i];
int ans = 0;
rep(i, 1, n + 1) ans = max(ans, abs(a[i] - a[i - 1]));
printf("%lld\n", ans);
}
return;
}
signed main()
{
cf();
return 0;
}
```
## 选项
### A
```c
#define ll long long
const int N = 3e5;
ll a[N], s[N];
bool vis[N];
int n;
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
memset(vis, 0, sizeof(vis));
scanf("%d", &n);
s[0] = 0;
for (int i = 1; i <= n; ++i)
{
scanf("%lld", &s[i]);
s[i] += s[i - 1];
}
ll s0 = 0, sn = s[n];
if (s0 > sn)
swap(s0, sn);
sort(s, s + n + 1);
int l = 0, r = n;
for (int i = lower_bound(s, s + n + 1, s0) - s; i >= 0; i -= 2)
{
a[l++] = s[i], vis[i] = 1;
}
for (int i = lower_bound(s, s + n + 1, sn) - s; i <= n; i += 2)
{
a[r--] = s[i], vis[i] = 1;
}
for (int i = 0; i <= n; ++i)
{
if (!vis[i])
a[l++] = s[i];
}
ll res = 0;
for (int i = 1; i <= n; ++i)
res = max(res, abs(a[i] - a[i - 1]));
printf("%lld\n", res);
}
return 0;
}
```
### B
```c
const int MAXN = 300010;
int nums[MAXN];
bool judgeYi(int a, int b)
{
return a > 0 && b < 0 || a < 0 && b > 0;
}
int main()
{
int T, n;
cin >> T;
while (T--)
{
cin >> n;
bool hasNe = false, hasPo = false;
int res = 0;
for (int i = 0; i < n; i++)
{
scanf("%d", &nums[i]);
if (nums[i] < 0)
{
hasNe = true;
}
else if (nums[i] > 0)
{
hasPo = true;
}
}
if (hasNe && hasPo)
{
bool canNext;
do
{
canNext = false;
for (int i = 1; i < n - 1; i++)
{
if (judgeYi(nums[i], nums[i - 1]) || judgeYi(nums[i], nums[i + 1]))
{
if (nums[i] > 0)
{
if (judgeYi(nums[i - 1], nums[i + 1]))
{
if ((nums[i - 1] > 0 && abs(nums[i + 1]) > nums[i - 1] + nums[i]) ||
(nums[i + 1] > 0 && abs(nums[i - 1]) > nums[i + 1] + nums[i]))
{
nums[i + 1] += nums[i];
nums[i - 1] += nums[i];
nums[i] = -nums[i];
canNext = true;
}
}
else
{
if (abs(nums[i - 1]) > nums[i] || abs(nums[i + 1]) > nums[i])
{
nums[i + 1] += nums[i];
nums[i - 1] += nums[i];
nums[i] = -nums[i];
canNext = true;
}
}
}
else if (nums[i] < 0)
{
if (judgeYi(nums[i - 1], nums[i + 1]))
{
if ((nums[i - 1] > 0 && nums[i - 1] > abs(nums[i + 1] + nums[i])) ||
(nums[i + 1] > 0 && nums[i + 1] > abs(nums[i - 1] + nums[i])))
{
nums[i + 1] += nums[i];
nums[i - 1] += nums[i];
nums[i] = -nums[i];
canNext = true;
}
}
else
{
if (nums[i - 1] > abs(nums[i]) || nums[i + 1] > abs(nums[i]))
{
nums[i + 1] += nums[i];
nums[i - 1] += nums[i];
nums[i] = -nums[i];
canNext = true;
}
}
}
}
}
} while (canNext);
}
int t;
for (int i = 0; i < n; i++)
{
res = max(res, abs(nums[i]));
}
cout << res << endl;
}
return 0;
}
```
### C
```c
typedef long long LL;
const int INF = 0x3f3f3f3f;
const double Pi = acos(-1);
namespace
{
template <typename T>
inline void read(T &x)
{
x = 0;
T f = 1;
char s = getchar();
for (; !isdigit(s); s = getchar())
if (s == '-')
f = -1;
for (; isdigit(s); s = getchar())
x = (x << 3) + (x << 1) + (s ^ 48);
x *= f;
}
}
#define fio \
ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0);
#define _for(n, m, i) for (register int i = (n); i < (m); ++i)
#define _rep(n, m, i) for (register int i = (n); i <= (m); ++i)
#define _srep(n, m, i) for (register int i = (n); i >= (m); i--)
#define _sfor(n, m, i) for (register int i = (n); i > (m); i--)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define lowbit(x) x &(-x)
#define pii pair<int, int>
#define fi first
#define se second
const int N = 1e6 + 5;
LL a[N];
LL ans[N];
bool vis[N];
LL Abs(LL x)
{
return x < 0 ? -x : x;
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
int n;
scanf("%d", &n);
a[0] = 0;
_rep(1, n, i)
{
scanf("%lld", a + i);
a[i] += a[i - 1];
}
LL a0 = 0, an = a[n], Max = 0;
int A0, AN;
sort(a, a + n + 1);
memset(vis, 0, sizeof vis);
if (a0 > an)
swap(a0, an);
_rep(0, n, i) if (a0 == a[i])
{
A0 = i;
break;
}
_rep(0, n, i) if (an == a[i])
{
AN = i;
break;
}
int l = 0, r = n;
for (int i = A0; i >= 0; i -= 2)
ans[l++] = a[i], vis[i] = 1;
for (int i = AN; i <= n; i += 2)
ans[r--] = a[i], vis[i] = 1;
_rep(0, n, i) if (!vis[i]) ans[l++] = a[i];
_rep(1, n, i) Max = max(Max, Abs(ans[i] - ans[i - 1]));
printf("%lld\n", Max);
}
}
```
# 三体攻击
**题目描述**
三体人将对地球发起攻击。为了抵御攻击,地球人派出了 A × B × C 艘战舰,在太空中排成一个 A 层 B 行 C 列的立方体。其中,第 i 层第 j 行第 k 列的战舰(记为战舰 (i, j, k))的生命值为 d(i, j, k)。
三体人将会对地球发起 m 轮“立方体攻击”,每次攻击会对一个小立方体中的所有战舰都造成相同的伤害。具体地,第 t 轮攻击用 7 个参数 la<sub>t</sub>, ra<sub>t</sub>, lb<sub>t</sub>, rb<sub>t</sub>, lc<sub>t</sub>, rc<sub>t</sub>, h<sub>t</sub> 描述;
所有满足 i ∈ [la<sub>t</sub>, ra<sub>t</sub>],j ∈ [lb<sub>t</sub>, rb<sub>t</sub>],k ∈ [lc<sub>t</sub>, rc<sub>t</sub>] 的战舰 (i, j, k) 会受到 h<sub>t</sub> 的伤害。如果一个战舰累计受到的总伤害超过其防御力,那么这个战舰会爆炸。
地球指挥官希望你能告诉他,第一艘爆炸的战舰是在哪一轮攻击后爆炸的。
**输入格式**
从标准输入读入数据。
第一行包括 4 个正整数 A, B, C, m;
第二行包含 A × B × C 个整数,其中第 ((i − 1)×B + (j − 1)) × C + (k − 1)+1 个数为 d(i, j, k);
第 3 到第 m + 2 行中,第 (t − 2) 行包含 7 个正整数 la<sub>t</sub>, ra<sub>t</sub>, lb<sub>t</sub>, rb<sub>t</sub>, lc<sub>t</sub>, rc<sub>t</sub>, h<sub>t</sub>
**输出格式**
输出到标准输出。
输出第一个爆炸的战舰是在哪一轮攻击后爆炸的。保证一定存在这样的战舰。
**样例输入**
```
2 2 2 3
1 1 1 1 1 1 1 1
1 2 1 2 1 1 1
1 1 1 2 1 2 1
1 1 1 1 1 1 2
```
**样例输出**
```
2
```
**样例解释**
在第 2 轮攻击后,战舰 (1,1,1) 总共受到了 2 点伤害,超出其防御力导致爆炸。
**数据约定**
```
对于 10% 的数据,B = C = 1;
对于 20% 的数据,C = 1;
对于 40% 的数据,A × B × C, m ≤ 10, 000;
对于 70% 的数据,A, B, C ≤ 200;
对于所有数据,A × B × C ≤ 10^6, m ≤ 10^6, 0 ≤ d(i, j, k), ht ≤ 10^9。
```
以下程序实现了这一功能,请你补全空白处的内容:
```c
#include <bits/stdc++.h>
using namespace std;
const int N = 2000010;
typedef long long LL;
int A, B, C, m;
LL s[N], b[N], bp[N];
int op[N / 2][7];
const int d[8][4] = {
{0, 0, 0, 1},
{0, 0, 1, -1},
{0, 1, 0, -1},
{0, 1, 1, 1},
{1, 0, 0, -1},
{1, 0, 1, 1},
{1, 1, 0, 1},
{1, 1, 1, -1}};
int get(int i, int j, int k)
{
return (i * B + j) * C + k;
}
bool check(int mid)
{
memcpy(b, bp, sizeof bp);
for (int i = 1; i <= mid; i++)
{
int x1 = op[i][0], x2 = op[i][1], y1 = op[i][2], y2 = op[i][3], z1 = op[i][4], z2 = op[i][5], h = op[i][6];
b[get(x1, y1, z1)] -= h;
b[get(x1, y1, z2 + 1)] += h;
b[get(x1, y2 + 1, z1)] += h;
b[get(x1, y2 + 1, z2 + 1)] -= h;
b[get(x2 + 1, y1, z1)] += h;
b[get(x2 + 1, y1, z2 + 1)] -= h;
b[get(x2 + 1, y2 + 1, z1)] -= h;
b[get(x2 + 1, y2 + 1, z2 + 1)] += h;
}
memset(s, 0, sizeof s);
for (int i = 1; i <= A; i++)
for (int j = 1; j <= B; j++)
for (int k = 1; k <= C; k++)
{
s[get(i, j, k)] = b[get(i, j, k)];
for (int u = 1; u < 8; u++)
{
int x = i - d[u][0], y = j - d[u][1], z = k - d[u][2], t = d[u][3];
s[get(i, j, k)] -= s[get(x, y, z)] * t;
}
if (s[get(i, j, k)] < 0)
return true;
}
return false;
}
int main()
{
scanf("%d%d%d%d", &A, &B, &C, &m);
for (int i = 1; i <= A; i++)
for (int j = 1; j <= B; j++)
for (int k = 1; k <= C; k++)
scanf("%lld", &s[get(i, j, k)]);
for (int i = 1; i <= A; i++)
for (int j = 1; j <= B; j++)
for (int k = 1; k <= C; k++)
for (int u = 0; u < 8; u++)
{
int x = i - d[u][0], y = j - d[u][1], z = k - d[u][2], t = d[u][3];
__________________
}
for (int i = 1; i <= m; i++)
for (int j = 0; j < 7; j++)
scanf("%d", &op[i][j]);
int l = 1, r = m;
while (l < r)
{
int mid = l + r >> 1;
if (check(mid))
r = mid;
else
l = mid + 1;
}
printf("%d\n", r);
return 0;
}
```
## 答案
```c
bp[get(i, j, k)] += s[get(x, y, z)] * t;
```
## 选项
### A
```c
bp[get(i, j, k)] = s[get(x, y, z)] * t;
```
### B
```c
bp[get(i, j, k)] *= s[get(x, y, z)] * t;
```
### C
```c
bp[get(i, j, k)] = s[get(x, y, z)] + t;
```
# 装饰珠
**题目描述**
在怪物猎人这一款游戏中,玩家可以通过给装备镶嵌不同的装饰珠来获取 相应的技能,以提升自己的战斗能力。
已知猎人身上一共有 6 件装备,每件装备可能有若干个装饰孔,每个装饰孔有各自的等级,可以镶嵌一颗小于等于自身等级的装饰珠 (也可以选择不镶嵌)。
装饰珠有 M 种,编号 1 至 M,分别对应 M 种技能,第 i 种装饰珠的等级为 L<sub>i</sub>,只能镶嵌在等级大于等于 L<sub>i</sub> 的装饰孔中。
对第 i 种技能来说,当装备相应技能的装饰珠数量达到 K<sub>i</sub>个时,会产生W<sub>i</sub>(K<sub>i</sub>)的价值,镶嵌同类技能的数量越多,产生的价值越大,即W<sub>i</sub>(K<sub>i-1</sub>)<W<sub>i</sub>(K<sub>i</sub>)。但每个技能都有上限P<sub>i</sub>(1≤P<sub>i</sub>≤7),当装备的珠子数量超过P<sub>i</sub>时,只会产生W<sub>i</sub>(P<sub>i</sub>)的价值。
对于给定的装备和装饰珠数据,求解如何镶嵌装饰珠,使得 6 件装备能得到的总价值达到最大。
**输入描述**
输入的第 1 至 6 行,包含 6 件装备的描述。其中第i行的第一个整数Ni表示第i件装备的装饰孔数量。后面紧接着Ni个整数,分别表示该装备上每个装饰孔的等级L(1≤ L ≤4)。
第 7 行包含一个正整数 M,表示装饰珠 (技能) 种类数量。
第 8 至 M + 7 行,每行描述一种装饰珠 (技能) 的情况。每行的前两个整数L<sub>j</sub>(1≤ L<sub>j</sub> ≤4)和P<sub>j</sub>(1≤ P<sub>j</sub> ≤7)分别表示第 j 种装饰珠的等级和上限。接下来P<sub>j</sub>个整数,其中第 k 个数表示装备该中装饰珠数量为 k 时的价值W<sub>j</sub>(k)。
其中1 ≤ N<sub>i</sub> ≤ 50,1 ≤ M ≤ 10<sup>4</sup>,1 ≤ W<sub>j</sub>(k) ≤ 10<sup>4</sup>
**输出描述**
输出一行包含一个整数,表示能够得到的最大价值。
**输入**
```
1 1
2 1 2
1 1
2 2 2
1 1
1 3
3
1 5 1 2 3 5 8
2 4 2 4 8 15
3 2 5 10
```
**输出**
```
20
```
**样例说明**
按照如下方式镶嵌珠子得到最大价值 20,括号内表示镶嵌的装饰珠的种类编号:
```
1: (1)
2: (1) (2)
3: (1)
4: (2) (2)
5: (1)
6: (2)
```
4 颗技能 1 装饰珠,4 颗技能 2 装饰珠 W<sub>1</sub>(4) + W<sub>2</sub>(4) = 5 + 15 = 20。W<sub>1</sub>(4)+W<sub>2</sub>(4)=5+15=20。
以下<span style="color:red">错误</span>的一项是?
## aop
### before
```c
#include <bits/stdc++.h>
using namespace std;
```
### after
```c
```
## 答案
```c
其他三个都不对
```
## 选项
### A
```c
int main()
{
vector<int> Hole(5);
int N, tmp, total = 0;
for (int i = 0; i < 6; ++i)
{
cin >> N;
for (int j = 0; j < N; ++j)
{
cin >> tmp;
++Hole[tmp];
++total;
}
}
cin >> N;
vector<int> L(N + 1);
vector<vector<int>> W(N + 1, vector<int>());
for (int i = 1; i <= N; ++i)
{
cin >> L[i];
cin >> tmp;
W[i].resize(tmp + 1);
for (int j = 1; j <= tmp; ++j)
{
cin >> W[i][j];
}
}
vector<vector<int>> dp(N + 1, vector<int>(total + 1));
int sum = 0;
int kind = 0;
for (int level = 4; level >= 1; --level)
{
sum += Hole[level];
if (sum == 0)
continue;
for (int k = 1; k <= N; ++k)
{
if (L[k] == level)
{
++kind;
for (int i = 1; i <= sum; ++i)
{
dp[kind][i] = dp[kind - 1][i];
}
for (int i = 1; i < W[k].size(); ++i)
{
for (int j = sum; j >= i; --j)
{
dp[kind][j] = max(dp[kind][j], dp[kind - 1][j - i] + W[k][i]);
}
}
}
}
}
cout << *max_element(dp[kind].begin(), dp[kind].end()) << endl;
return 0;
}
```
### B
```c
int Solution()
{
int n, sum = 0, L[5] = {0}, m, M, W[5][10] = {0}, le, P, res = 0;
for (int i = 0; i < 6; i++)
{
cin >> n;
sum += n;
for (int j = 0; j < n; j++)
{
cin >> m;
L[m]++;
}
}
cin >> M;
int ww;
for (int i = 0; i < M; i++)
{
cin >> le >> P;
for (int j = 1; j <= P; j++)
{
cin >> ww;
if (ww > W[le][j])
W[le][j] = ww;
if ((j + 1 > P) && P < 7)
for (int k = j + 1; k <= 7; k++)
W[le][k] = W[le][k - 1];
}
}
for (int i = 0; i <= L[4]; i++)
{
for (int j = 0; j <= (sum - L[1] - L[2] - i); j++)
{
for (int k = 0; k <= (sum - L[1] - (i + j)); k++)
{
for (int s = 0; s <= (sum - (i + j + k)); s++)
{
int a, b, c, d;
if (i > 7)
a = 7;
else
a = i;
if (j > 7)
b = 7;
else
b = j;
if (k > 7)
c = 7;
else
c = k;
if (s > 7)
d = 7;
else
d = s;
res = max(res, W[4][a] + W[3][b] + W[2][c] + W[1][d]);
}
}
}
}
return res;
}
int main()
{
cout << Solution();
return 0;
}
```
### C
```c
constexpr size_t MAXN = 55, MAXS = 305, MAXM = 1e4 + 5;
int n[MAXN], cnt[5], Lv[MAXM], p[MAXM], w[MAXM][MAXN];
int dp[MAXM][MAXS];
int m;
inline void Read()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
for (int i = 1; i <= 6; i++)
{
cin >> n[i];
for (int j = 1, x; j <= n[i]; j++)
{
cin >> x;
cnt[x]++;
}
}
cin >> m;
for (int i = 1; i <= m; i++)
{
cin >> Lv[i] >> p[i];
for (int j = 1; j <= p[i]; j++)
cin >> w[i][j];
}
}
inline int DP()
{
memset(dp, 0x80, sizeof dp), dp[0][0] = 0;
int ans = 0, sum = 0, tot = 0;
for (int L = 4; L >= 1; L--)
{
sum += cnt[L];
for (int i = 1; i <= m; i++)
if (Lv[i] == L)
{
tot++;
for (int k = 0; k <= sum; k++)
dp[tot][k] = dp[tot - 1][k];
for (int j = 1; j <= p[i]; j++)
for (int k = j; k <= sum; k++)
dp[tot][k] = max(dp[tot][k], dp[tot - 1][k - j] + w[i][j]);
}
}
for (int i = 0; i <= sum; i++)
ans = max(ans, dp[tot][i]);
return ans;
}
signed main()
{
Read();
cout << DP();
}
```
# 组合数问题
**问题描述**
给 n, m, k, 求有多少对(i, j)满足 1 ≤ i ≤ n, 0 ≤ j ≤ min(i, m) 且C<sub>i</sub><sup>j</sup>≡0(mod k),k 是质数。其中C<sub>i</sub><sup>j</sup>是组合数,表示从 i 个不同的数中选出 j 个组成一个集合的方案数。
**输入格式**
第一行两个数 t, k,其中 t 代表该测试点包含 t 组询问,k 的意思与上文中相同。
接下来 t 行每行两个整数 n, m,表示一组询问。
**输出格式**
输出 t 行,每行一个整数表示对应的答案。由于答案可能很大,请输出答案除以 109 + 7 的余数。
**样例输入**
```
1 2
3 3
```
**样例输出**
```
1
```
**样例说明**
在所有可能的情况中,只有 C<sub>2</sub><sup>1</sup> 是 2 的倍数。
**样例输入**
```
2 5
4 5
6 7
```
**样例输出**
```
0
7
```
**样例输入**
```
3 23
23333333 23333333
233333333 233333333
2333333333 2333333333
```
**样例输出**
```
851883128
959557926
680723120
```
**数据规模和约定**
```
对于所有评测用例,1 ≤ k ≤ 108, 1 ≤ t ≤ 105, 1 ≤ n, m ≤ 1018,且 k 是质数。评测时将使用 10 个评测用例测试你的程序
```
以下选项<span style="color:red">错误</span>的是?
## 答案
```c
其他三项都是错的
```
## 选项
### A
```c
const int Mod = 1e9 + 7;
int c[2010][2010];
int main()
{
int n, m, t, k;
cin >> t >> k;
int nn = 2000, mm = 2000;
for (int i = 0; i <= nn; i++)
{
c[i][0] = 1;
c[i][i] = 1;
}
for (int i = 1; i <= nn; i++)
for (int j = 1; j <= mm; j++)
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % k;
while (t--)
{
cin >> n >> m;
int ans = 0;
for (int j = 0; j <= m; j++)
for (int i = j; i <= n; i++)
if (c[i][j] == 0)
ans++;
cout << ans % Mod;
}
return 0;
}
```
### B
```c
#define modk(x) (((x) >= k) ? ((x)-k) : (x))
const int maxn = 2005;
int c[maxn][maxn], n, m, k, T;
void init()
{
c[0][0] = 1;
for (int i = 1; i < maxn; i++)
{
c[i][0] = 1 % k;
for (int j = 1; j <= i; j++)
{
c[i][j] = modk(c[i - 1][j] + c[i - 1][j - 1]);
}
}
for (int i = 0; i < maxn; i++)
{
for (int j = 0; j <= i; j++)
{
if (c[i][j] == 0)
c[i][j] = 1;
else
c[i][j] = 0;
}
}
for (int i = 1; i < maxn; i++)
{
int s = 0;
for (int j = 0; j < maxn; j++)
{
s += c[i][j];
c[i][j] = c[i - 1][j] + s;
}
}
}
int main()
{
scanf("%d%d", &T, &k);
init();
while (T--)
{
scanf("%d%d", &n, &m);
printf("%d\n", c[n][m]);
}
return 0;
}
```
### C
```c
const int Mod = 1e9 + 7;
const int inv_2 = 5e8 + 4;
long long cal(long long x, long long y)
{
if (x < y)
{
x %= Mod;
return (x + 2) * (x + 1) % Mod * inv_2 % Mod;
}
x %= Mod, y %= Mod;
return ((y + 2) * (y + 1) % Mod * inv_2 % Mod + (x - y) * (y + 1) % Mod) % Mod;
}
long long cal_1(long long x, long long y)
{
return min(x, y) + 1;
}
long long cal_2(long long x, long long y)
{
if (x < y)
{
return 0;
}
return x - y + 1;
}
int main()
{
int t, k;
cin >> t >> k;
long long n, m;
int a[100], b[100];
for (int turn = 0; turn < t; ++turn)
{
cin >> n >> m;
if (m > n)
m = n;
long long ans = cal(n, m);
int len_a = 0, len_b = 0;
while (n)
{
a[len_a++] = n % k;
n /= k;
}
while (m)
{
b[len_b++] = m % k;
m /= k;
}
int len = max(len_a, len_b);
vector<vector<long long>> dp(len + 1, vector<long long>(4));
dp[len][3] = 1;
for (int i = len - 1; i >= 0; --i)
{
dp[i][0] = dp[i + 1][0] * cal(k - 1, k - 1) + dp[i + 1][1] * cal(a[i] - 1, k - 1) + dp[i + 1][2] * cal(k - 1, b[i] - 1) + dp[i + 1][3] * cal(a[i] - 1, b[i] - 1);
dp[i][1] = dp[i + 1][1] * cal_1(a[i], k - 1) + dp[i + 1][3] * cal_1(a[i], b[i] - 1);
dp[i][2] = dp[i + 1][2] * cal_2(k - 1, b[i]) + dp[i + 1][3] * cal_2(a[i] - 1, b[i]);
dp[i][3] = dp[i + 1][3] & (a[i] >= b[i]);
dp[i][0] %= Mod, dp[i][1] %= Mod;
dp[i][2] %= Mod, dp[i][3] %= Mod;
}
ans -= dp[0][0] + dp[0][1] + dp[0][2] + dp[0][3];
ans %= Mod;
if (ans < 0)
ans += Mod;
cout << ans << endl;
}
return 0;
}
```
# 糖果
糖果店的老板一共有M种口味的糖果出售。为了方便描述,我们将M种口味编号1~M。
小明希望能品尝到所有口味的糖果。遗憾的是老板并不单独出售糖果,而是K颗一包整包出售。
幸好糖果包装上注明了其中K颗糖果的口味,所以小明可以在买之前就知道每包内的糖果口味。
给定包糖果,请你计算小明最少买几包,就可以品尝到所有口味的糖果。
**输入**
第一行包含三个整数N、M 和K。
接下来N 行每行K 这整数T<sub>1</sub>,T<sub>2</sub>,…,T<sub>K</sub>,代表一包糖果的口味。
1<=N<=100,1<=M<=20,1<=K<=20,1<=T<sub>i</sub><=M。
**输出**
一个整数表示答案。如果小明无法品尝所有口味,输出-1。
**样例输入**
```
6 5 3
1 1 2
1 2 3
1 1 3
2 3 5
5 4 2
5 1 2
```
**样例输出**
```
2
```
以下<span style="color:red">错误</span>的一项是?
## aop
### before
```c
#include <bits/stdc++.h>
using namespace std;
```
### after
```c
```
## 答案
```c
const int N = 105, M = (1 << 20) + 10;
int n, m, k, x, a[N], dp[M];
int main()
{
ios::sync_with_stdio(false);
cin >> n >> m >> k;
memset(dp, -1, sizeof(dp));
for (int i = 1; i <= n; i++)
{
int s = 0;
for (int j = 1; j <= k; j++)
{
cin >> x;
s |= (1 << (x - 1));
}
dp[s] = 1;
a[i] = s;
}
for (int i = 1; i <= n; i++)
{
for (int j = 0; j < (1 << m); j++)
{
if (dp[j] == -1)
continue;
int to = j | a[i];
if (dp[to] != -1)
{
dp[to] = min(dp[to], dp[j]);
}
else
{
dp[to] = dp[j] + 1;
}
}
}
printf("%d\n", dp[(1 << m) - 1]);
return 0;
}
```
## 选项
### A
```c
int n, m, k;
int dp[1 << 20];
vector<int> a;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m >> k;
for (int i = 0; i < (1 << m); i++)
{
dp[i] = 9999;
}
for (int i = 0; i < n; i++)
{
int s = 0;
for (int i = 0; i < k; i++)
{
int temp;
cin >> temp;
s |= 1 << (temp - 1);
}
a.push_back(s);
}
dp[0] = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < (1 << m); j++)
{
if (dp[j] == 9999 || (j | a[i]) == j)
continue;
dp[j | a[i]] = min(dp[j] + 1, dp[j | a[i]]);
}
}
if (dp[(1 << m) - 1] == 9999)
cout << -1;
else
cout << dp[(1 << m) - 1];
return 0;
}
```
### B
```c
const int maxn = (1 << 20) + 52;
const int inf = 9;
int a[505], n, m, k, dp[2][maxn];
int min(int a, int b, int c)
{
return min(min(a, b), c);
}
int main()
{
scanf("%d%d%d", &n, &m, &k);
int e = 1 << m;
for (int i = 1; i <= n; i++)
{
a[i] = 0;
for (int j = 0; j < k; j++)
{
int temp;
scanf("%d", &temp);
a[i] = a[i] | 1 << (temp - 1);
}
}
for (int i = 0; i < maxn; i++)
{
dp[0][i] = dp[1][i] = inf;
}
dp[0][0] = 0;
bool pos = 1;
for (int i = 1; i <= n; i++, pos = !pos)
{
for (int j = 0; j < e; j++)
{
dp[pos][j] = dp[!pos][j];
}
for (int j = 0; j < e; j++)
{
dp[pos][j | a[i]] = min(dp[pos][j | a[i]], dp[!pos][j | a[i]], dp[!pos][j] + 1);
}
}
if (dp[!pos][e - 1] == inf)
{
printf("-1\n");
}
else
printf("%d\n", dp[!pos][e - 1]);
return 0;
}
```
### C
```c
int dp[1 << 20];
int ST[100];
int main()
{
int n, m, k;
cin >> n >> m >> k;
int tot = (1 << m) - 1;
memset(dp, -1, sizeof dp);
for (int i = 0; i < n; i++)
{
int st = 0;
for (int j = 0; j < k; j++)
{
int x;
cin >> x;
st |= (1 << x - 1);
}
dp[st] = 1;
ST[i] = st;
}
for (int i = 0; i <= tot; i++)
{
if (dp[i] != -1)
{
for (int j = 0; j < n; j++)
{
int st = ST[j];
if (dp[i | st] == -1 || dp[i | st] > dp[i] + 1)
dp[i | st] = dp[i] + 1;
}
}
}
cout << dp[tot];
return 0;
}
```
# 垒骰子
赌圣atm晚年迷恋上了垒骰子,就是把骰子一个垒在另一个上边,不能歪歪扭扭,要垒成方柱体。
经过长期观察,atm 发现了稳定骰子的奥秘:有些数字的面贴着会互相排斥!
我们先来规范一下骰子:1 的对面是 4,2 的对面是 5,3 的对面是 6。
假设有 m 组互斥现象,每组中的那两个数字的面紧贴在一起,骰子就不能稳定的垒起来。
atm想计算一下有多少种不同的可能的垒骰子方式。
两种垒骰子方式相同,当且仅当这两种方式中对应高度的骰子的对应数字的朝向都相同。
由于方案数可能过多,请输出模 10<sup>9</sup> + 7 的结果。
不要小看了 atm 的骰子数量哦~
**输入格式**
第一行两个整数 n m
n表示骰子数目
接下来 m 行,每行两个整数 a b ,表示 a 和 b 数字不能紧贴在一起。
**输出格式**
一行一个数,表示答案模 10<sup>9</sup> + 7 的结果。
**样例输入**
```
2 1
1 2
```
**样例输出**
```
544
```
**数据范围**
```
对于 30% 的数据:n <= 5
对于 60% 的数据:n <= 100
对于 100% 的数据:0 < n <= 10^9, m <= 36
```
**资源约定:**
峰值内存消耗 < 256M
CPU消耗 < 2000ms
以下选项<span style="color:red">错误</span>的是?
## aop
### before
```c
#include <bits/stdc++.h>
using namespace std;
```
### after
```c
```
## 答案
```c
#define MOD 1000000007
using namespace std;
int points[7] = {0, 4, 5, 6, 1, 2, 3};
int n, m;
int ban[36][2];
long long result;
bool judge(int point1, int point2)
{
bool flag = true;
for (int i = 0; i < m; i++)
{
int point3 = points[point2];
if (point1 == ban[i][0] && point3 == ban[i][1])
{
flag = false;
break;
}
if (point1 == ban[i][1] && point3 == ban[i][0])
{
flag = false;
break;
}
}
return flag;
}
void dfs(int cnt, int point)
{
if (cnt == n)
{
result++;
return;
}
for (int i = 1; i <= 6; i++)
{
if (judge(point, i))
{
cnt++;
dfs(cnt, i);
cnt--;
}
}
}
long long quickpow(int x, int N)
{
int reg = x;
int sum = 1;
while (N)
{
if (N & 1)
{
sum = sum * reg;
}
reg *= reg;
N = N >> 1;
}
return sum;
}
int main()
{
cin >> n >> m;
for (int i = 0; i < m; i++)
{
cin >> ban[i][0] >> ban[i][1];
}
dfs(0, 0);
long long temp = quickpow(4, n);
cout << result * temp % MOD;
return 0;
}
```
## 选项
### A
```c
#define MOD 1000000007
typedef long long LL;
LL dp[2][7];
int n, m;
bool conflict[7][7];
map<int, int> op;
void init()
{
op[1] = 4;
op[4] = 1;
op[2] = 5;
op[5] = 2;
op[3] = 6;
op[6] = 3;
}
struct M
{
LL a[6][6];
M()
{
for (int i = 0; i < 6; ++i)
{
for (int j = 0; j < 6; ++j)
{
a[i][j] = 1;
}
}
}
};
M mMultiply(M m1, M m2)
{
M ans;
for (int i = 0; i < 6; ++i)
{
for (int j = 0; j < 6; ++j)
{
ans.a[i][j] = 0;
for (int k = 0; k < 6; ++k)
{
ans.a[i][j] = (ans.a[i][j] + m1.a[i][k] * m2.a[k][j]) % MOD;
}
}
}
return ans;
}
M mPow(M m, int k)
{
M ans;
for (int i = 0; i < 6; ++i)
{
for (int j = 0; j < 6; ++j)
{
if (i == j)
ans.a[i][j] = 1;
else
ans.a[i][j] = 0;
}
}
while (k)
{
if (k & 1)
{
ans = mMultiply(ans, m);
}
m = mMultiply(m, m);
k >>= 1;
}
return ans;
}
int main()
{
init();
scanf("%d%d", &n, &m);
M cMatrix;
for (int i = 0; i < m; ++i)
{
int a, b;
scanf("%d%d", &a, &b);
cMatrix.a[op[a] - 1][b - 1] = 0;
cMatrix.a[op[b] - 1][a - 1] = 0;
}
M cMatrix_n_1 = mPow(cMatrix, n - 1);
LL ans = 0;
for (int j = 0; j < 6; ++j)
{
for (int i = 0; i < 6; ++i)
{
ans = (ans + cMatrix_n_1.a[i][j]) % MOD;
}
}
LL t = 1;
LL tmp = 4;
LL p = n;
while (p)
{
if (p & 1)
{
t = t * tmp % MOD;
}
tmp = tmp * tmp % MOD;
p >>= 1;
}
printf("%lld", ans * t % MOD);
return 0;
}
```
### B
```c
#define MOD 1000000007
typedef long long LL;
LL dp[2][7];
int n, m;
bool conflict[7][7];
map<int, int> op;
void init()
{
op[1] = 4;
op[4] = 1;
op[2] = 5;
op[5] = 2;
op[3] = 6;
op[6] = 3;
}
int main()
{
init();
scanf("%d%d", &n, &m);
for (int i = 0; i < m; ++i)
{
int a, b;
scanf("%d%d", &a, &b);
conflict[a][b] = true;
conflict[b][a] = true;
}
for (int j = 1; j <= 6; ++j)
{
dp[0][j] = 1;
}
int cur = 0;
for (int level = 2; level <= n; ++level)
{
cur = 1 - cur;
for (int j = 1; j <= 6; ++j)
{
dp[cur][j] = 0;
for (int i = 1; i <= 6; ++i)
{
if (conflict[op[j]][i])
continue;
dp[cur][j] = (dp[cur][j] + dp[1 - cur][i]) % MOD;
}
}
}
LL sum = 0;
for (int k = 1; k <= 6; ++k)
{
sum = (sum + dp[cur][k]) % MOD;
}
LL ans = 1;
LL tmp = 4;
LL p = n;
while (p)
{
if (p & 1)
ans = (ans * tmp) % MOD;
tmp = (tmp * tmp) % MOD;
p >>= 1;
}
printf("%lld\n", (sum * ans) % MOD);
return 0;
}
```
### C
```c
#define MOD 1000000007
int op[7];
bool confilct[7][7];
void init()
{
op[1] = 4;
op[4] = 1;
op[2] = 5;
op[5] = 2;
op[3] = 6;
op[6] = 3;
}
int n, m;
long long int f(int up, int count)
{
if (count == 0)
return 4;
long long ans = 0;
for (int upp = 1; upp <= 6; ++upp)
{
if (confilct[op[up]][upp])
continue;
ans = (ans + f(upp, count - 1)) % MOD;
}
return ans;
}
int main()
{
init();
scanf("%d%d", &n, &m);
for (int i = 0; i < m; ++i)
{
int x, y;
scanf("%d%d", &x, &y);
confilct[y][x] = true;
confilct[x][y] = true;
}
long long ans = 0;
for (int up = 1; up <= 6; ++up)
{
ans = (ans + 4 * f(up, n - 1)) % MOD;
}
printf("%lli\n", ans);
return 0;
}
```
...@@ -616,6 +616,35 @@ def fixbug_for_md(): ...@@ -616,6 +616,35 @@ def fixbug_for_md():
f.write(solution_md_data) f.write(solution_md_data)
def delete_md_md_file():
count = 0
dirs = ['data/2.算法中阶', 'data/3.算法高阶', 'data/1.算法初阶']
exercises_ids = []
for dir in dirs:
dirs_ = os.listdir(dir)
algo_floor_dirs = []
for algo_floor_dir in dirs_:
leetcode_class_dir = os.path.join(dir, algo_floor_dir)
if os.path.isdir(leetcode_class_dir):
algo_floor_dirs.append(leetcode_class_dir)
for algo_floor_dir in algo_floor_dirs:
exercises_dirs_ = os.listdir(algo_floor_dir)
exercises_dirs = []
for exercises_dir_ in exercises_dirs_:
exercises_dir = os.path.join(algo_floor_dir, exercises_dir_)
if os.path.isdir(exercises_dir):
exercises_dirs.append(exercises_dir)
for idx, tem_dir in enumerate(exercises_dirs):
print(tem_dir)
solution_md_path = os.path.join(tem_dir, 'solution.md.md')
if os.path.exists(solution_md_path):
os.remove(solution_md_path)
print("delete {}".format(solution_md_path))
if helper_function == 'count_tag_class': if helper_function == 'count_tag_class':
count_tag_class() count_tag_class()
if helper_function == 'count_exercises': if helper_function == 'count_exercises':
...@@ -631,3 +660,5 @@ if helper_function == 'modify_back_up_dir_name': ...@@ -631,3 +660,5 @@ if helper_function == 'modify_back_up_dir_name':
# leetcode_helper_update_md() # leetcode_helper_update_md()
# leetcode_helper_update_config() # leetcode_helper_update_config()
delete_md_md_file()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册