Homework Introduction
function
#include <bits/stdc++.h>
using namespace std;
#define int long long
int f[25][25][25];
int w(int a, int b, int c) {
if (a <= 0 || b <= 0 || c <= 0)
return 1;
if (a > 20 || b > 20 || c > 20) {
if (f[20][20][20])
return f[20][20][20];
f[20][20][20] = w(20, 20, 20);
return f[20][20][20];
}
if (a < b && b < c) {
if ( f[a][b][c])
return f[a][b][c];
f[a][b][c] = w(a, b, c - 1) + w(a, b - 1, c - 1) - w(a, b - 1, c);
return f[a][b][c];
}
if ( f[a][b][c])
return f[a][b][c];
f[a][b][c] = w(a - 1, b, c) + w(a - 1, b - 1, c) + w(a - 1, b, c - 1) - w(a - 1, b - 1, c - 1);
return f[a][b][c];
}
int a, b, c;
signed main() {
while (1) {
cin >> a >> b >> c;
if (a == -1 && b == -1 && c == -1)
break;
printf("w(%lld, %lld, %lld) = %lld\n", a, b, c, w(a, b, c));
}
return 0;
}
小A点菜
// 其实这里的核心也是组合问题,就是从n道菜里面选择菜
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL f[105][10005], n, m, v[105], ans;
// f[i][j]表示当前选中了第i道菜,还剩j块钱
// c 是当前考虑的菜的顺序,k 是剩下的钱
LL dfs(LL c, LL k) {
// 之前计算过了
if (f[c][k])return f[c][k];
// 当前菜的价格超过了剩余的钱的数量
if (v[c] > k)return 0;
// 钱刚好相等,那就只有一种方案
if (v[c] == k)return 1;
for (LL i = c + 1; i <= n; i++)
// 考虑选择当前的菜色的方案,然后再和其他菜配对的可能
f[c][k] += dfs(i, k - v[c]);
return f[c][k];
}
int main() {
scanf("%lld%lld", &n, &m);
for (LL i = 1; i <= n; i++)
scanf("%lld", &v[i]);
// 遍历每一个菜,看能否凑成m的钱数
for (LL i = 1; i <= n; i++)
ans += dfs(i, m);
printf("%lld\n", ans);
return 0;
}
黑白棋子的移动
#include <bits/stdc++.h>
using namespace std;
const int N = 205;
int n;
char a[N];
// 当n等于4的时候是没有规律的,直接打表
string b[4] = {"ooo*o**--", "o--*o**oo", "o*o*o*--o", "--o*o*o*o"};
void shuchu(int l, int r) {
for (int i = l; i <= r; i++)
cout << a[i];
cout << endl;
}
// 递归n的问题可以化简为n-1的问题
// 然后n等于四的时候是没有规律的,直接代表输出
void f(int step) {
if (step == 3) {
for (int i = 0; i < 4; i++) {
cout << b[i]; // 输出前9个数字
shuchu(10, 2 * n + 2);
}
return ;
}
// n的问题转化为n-1的问题,需要进行了两步操作
shuchu(1, 2 * n + 2);
swap(a[step], a[step * 2 + 1]);
swap(a[step + 1], a[step * 2 + 2]);
shuchu(1, 2 * n + 2);
swap(a[step], a[step * 2 - 1]);
swap(a[step + 1], a[step * 2]);
f(step - 1);
}
int main() {
cin >> n;
// 重置开始状态
for (int i = 1; i <= n; i++) {
a[i] = 'o';
a[i + n] = '*';
}
a[2 * n + 1] = '-';
a[2 * n + 2] = '-';
// 开始递归
f(n);
return 0;
}
奇迹
#include <bits/stdc++.h>
using namespace std;
int day[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int f[100000005], res[6000005], cnt, date[15], num, ans;
char s[15];
bool is_run(int y) {
if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0)
return 1;
return 0;
}
bool legal(int y, int m, int d) {
if (m > 12 || m == 0 || d == 0 || y == 0)return 0;
if (m == 2) {
if (is_run(y)) {
if (d > 29)return 0;
return 1;
} else {
if (d > 28)return 0;
return 1;
}
} else {
if (d > day[m])return 0;
return 1;
}
}
void dfs(int d) {
if (d == 8) {
int y = num / 10000, m = (num % 10000) / 100, d = num % 100;
if (legal(y, m, d))
if ((!f[d]) && (!f[m * 100 + d]) && (!f[num]))ans++;
return;
}
if (date[d] != -1) {
num = num * 10 + date[d];
dfs(d + 1);
num /= 10; // 回溯,可能这个执行完毕以后,虽然当前的价值在当前点不会影响,
// 但是对之前的点可能会有影响
return;
}
for (int i = 0; i <= 9; i++) {
// 搜索优化,编号分别为: 0 1 2 3 4 5 6 7
if (d == 4 && i == 2)break;
if (d == 5 && i == 0 && date[d - 1] == 0)continue;
if (d == 5 && date[4] * 10 + i > 12)break;
if (d == 6 && i == 4)break;
date[d] = i;
num = num * 10 + i;
dfs(d + 1);
date[d] = -1;
num /= 10;
}
}
int main() {
int t;
scanf("%d", &t);
f[0] = f[1] = 1;
for (long long i = 2; i <= 99991231; i++) {
if (!f[i])res[++cnt] = i;
for (long long j = 1; j <= cnt && i * res[j] <= 99991231; j++) {
f[i * res[j]] = 1;
if (i % res[j] == 0)break;
}
}
while (t--) {
ans = 0;
scanf("%s", s);
for (int i = 0; i < 8; i++) {
if (s[i] == '-')date[i] = -1;
else date[i] = s[i] - '0';
}
dfs(0);
printf("%d\n", ans);
}
return 0;
}
Problem
Please claim the assignment to see the problems.
- Status
- Live...
- Problem
- 27
- Open Since
- 2025-8-7 0:00
- Deadline
- 2025-8-31 23:59
- Extension
- 24 hour(s)