2021牛客暑期多校训练营3 F.24dian 暴搜dfs
Posted kaka0010
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021牛客暑期多校训练营3 F.24dian 暴搜dfs相关的知识,希望对你有一定的参考价值。
原题链接:https://ac.nowcoder.com/acm/contest/11254/F
题意
用n张[1,13]的卡片凑出m,可以用加减乘除操作,要求可行的方案在运算中必须出现分数,最后计算出总方案数并输出。
分析
由于数据量不大,直接枚举就可以了。值得注意的是,n在<=3的情况下是肯定无解的。我们只要四层for循环去枚举所有卡片,然后判断是否可行。有一个优化的小技巧,我们先把四张卡片排序,然后用vis数组储存,如果遍历过直接跳过即可。
然后看怎么判断是否可行,刚开始有n张卡,我们暴力枚举两个数,对它们进行操作,然后放回数组,递归求解,如果有一组解可以不通过分数运算得到答案,我们就返回不可行。
Code
#include <bits/stdc++.h>
#define lowbit(i) i & -i
#define Debug(x) cout << x << endl
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const ll INF = 1e18;
const double eps = 1e-3;
const int N = 1e5 + 10;
const int M = 1e6 + 10;
const int MOD = 998244353;
struct node {
int x1, x2, x3, x4;
};
vector<node> ans;
bool check(double x) {//是否出现分数
return fabs(int(x) - x) > eps;
}
int ff = 0, f = 0;
int vis[15][15][15][15];
void dfs(vector<double> a, int b, bool flag) {
if (a.size() == 1) {
if (fabs(a[0] - b) < eps) {
if (!flag) ff = 1;
f = 1;
}
return;
}
for (int i = 0; i < a.size(); i++) {
for (int j = 0; j < a.size(); j++) {
if (i == j) continue;
vector<double> tmp = a;
double tmp1 = a[i], tmp2 = a[j];
a.erase(a.begin() + max(i, j));
a.erase(a.begin() + min(i, j));
a.push_back(tmp1 + tmp2);
dfs(a, b, flag | check(tmp1 + tmp2));
a = tmp;
a.erase(a.begin() + max(i, j));
a.erase(a.begin() + min(i, j));
a.push_back(tmp1 * tmp2);
dfs(a, b, flag | check(tmp1 * tmp2));
if (tmp2 != 0) {
a = tmp;
a.erase(a.begin() + max(i, j));
a.erase(a.begin() + min(i, j));
a.push_back(tmp1 / tmp2);
dfs(a, b, flag | check(tmp1 / tmp2));
}
a = tmp;
a.erase(a.begin() + max(i, j));
a.erase(a.begin() + min(i, j));
a.push_back(tmp1 - tmp2);
dfs(a, b, flag | check(tmp1 - tmp2));
a = tmp;
}
}
}
void solve() {
int n, m; cin >> n >> m;
if (n <= 3) {
cout << 0 << endl;
return;
}
for (int a = 1; a <= 13; a++) {
for (int b = 1; b <= 13; b++) {
for (int c = 1; c <= 13; c++) {
for (int d = 1; d <= 13; d++) {
vector<double> v;
v.push_back(a);
v.push_back(b);
v.push_back(c);
v.push_back(d);
sort(v.begin(), v.end());
if (vis[(int)v[0]][(int)v[1]][(int)v[2]][(int)v[3]]) continue;
vis[(int)v[0]][(int)v[1]][(int)v[2]][(int)v[3]] = 1;
ff = f = 0;
dfs(v, m, false);
if (f && !ff) ans.push_back({a, b, c, d});
}
}
}
}
cout << ans.size() << endl;
for (auto it : ans) {
cout << it.x1 << " " << it.x2 << " " << it.x3 << " " << it.x4 << endl;
}
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#ifdef ACM_LOCAL
freopen("input", "r", stdin);
freopen("output", "w", stdout);
signed test_index_for_debug = 1;
char acm_local_for_debug = 0;
do {
if (acm_local_for_debug == '$') exit(0);
if (test_index_for_debug > 20)
throw runtime_error("Check the stdin!!!");
auto start_clock_for_debug = clock();
solve();
auto end_clock_for_debug = clock();
cout << "Test " << test_index_for_debug << " successful" << endl;
cerr << "Test " << test_index_for_debug++ << " Run Time: "
<< double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
cout << "--------------------------------------------------" << endl;
} while (cin >> acm_local_for_debug && cin.putback(acm_local_for_debug));
#else
solve();
#endif
return 0;
}
以上是关于2021牛客暑期多校训练营3 F.24dian 暴搜dfs的主要内容,如果未能解决你的问题,请参考以下文章
2021牛客暑期多校训练营1 - F - Find 3-friendly Integers - 题解