Countdown
.
.
题意:给出6个数,通过+、-、*、/、四种操作,每个数只能用一次,问怎么算能得到一个尽量接近target的数(target给定),然后按题目要求输出。
.
.
解法:这题直接暴力死做不会超时,用map记录数字使用情况以及得出来的值,保存一下是从那两个状态转移过来就好了。.
.
.
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <map>
#include <algorithm>
#include <vector>
using namespace std;
struct Node {
int val, state;
Node() {}
Node(int _v, int _s):val(_v), state(_s) {}
void operator=(Node &other) {
val = other.val;
state = other.state;
}
bool operator<(const Node &other) const {
if (val < other.val) return true;
if (val > other.val) return false;
if (state < other.state) return true;
return false;
}
bool operator==(const Node &other) const {
if (val == other.val && state == other.state) return true;
return false;
}
bool operator!=(const Node &other) const {
if (*this == other) return false;
return true;
}
};
struct Pre {
Node p1, p2;
};
map<Node, Pre> store;
vector<Node> f[1<<6];
Pre d[400000];
int val[400000];
Node ans;
int tot, x, y, tar, a[10], sum, n, m;
int main() {
freopen("j.in","r",stdin);
int tt;
Node start(0, 0);
scanf("%d", &tt);
for (int cases = 1; cases <= tt; cases++) {
if (cases > 1) printf("\n");
store.clear();
for (int i = 0; i < 1<<6; i++) f[i].clear();
for (int i = 1; i <= 6; i++) scanf("%d", &a[i]);
scanf("%d", &tar);
ans.val = 1000000;
for (int i = 1; i <= 6; i++) {
Node temp(a[i], 1<<(i-1));
f[1<<(i-1)].push_back(temp);
store[temp].p1 = start;
store[temp].p2 = start;
if (abs(tar-a[i]) < abs(tar-ans.val)) {
ans.val = a[i];
ans.state = 1<<(i-1);
}
}
for (int i = 1; i <= (1<<6)-1; i++) {
for (int jj = 1; jj <= (1<<6)-1; jj++) {
for (int kk = jj+1; kk <= (1<<6)-1; kk++)
if (((jj|kk) == i) && ((jj&kk) == 0)) {
n = f[jj].size();
m = f[kk].size();
for (int j = 0; j < n; j++)
for (int k = 0; k < m; k++) {
Node temp;
temp.state = i;
// +
temp.val = f[jj][j].val+f[kk][k].val;
if (!store.count(temp)) {
f[i].push_back(temp);
if (abs(tar-temp.val) < abs(tar-ans.val)) ans = temp;
store[temp].p1 = f[jj][j];
store[temp].p2 = f[kk][k];
}
// *
temp.val = f[jj][j].val*f[kk][k].val;
if (!store.count(temp)) {
f[i].push_back(temp);
if (abs(tar-temp.val) < abs(tar-ans.val)) ans = temp;
store[temp].p1 = f[jj][j];
store[temp].p2 = f[kk][k];
}
// -
temp.val = f[jj][j].val-f[kk][k].val;
if (temp.val > 0 && !store.count(temp)) {
f[i].push_back(temp);
if (abs(tar-temp.val) < abs(tar-ans.val)) ans = temp;
store[temp].p1 = f[jj][j];
store[temp].p2 = f[kk][k];
}
temp.val = -f[jj][j].val+f[kk][k].val;
if (temp.val > 0 && !store.count(temp)) {
f[i].push_back(temp);
if (abs(tar-temp.val) < abs(tar-ans.val)) ans = temp;
store[temp].p1 = f[jj][j];
store[temp].p2 = f[kk][k];
}
// /
if (f[kk][k].val != 0 && f[jj][j].val%f[kk][k].val == 0) {
temp.val = f[jj][j].val/f[kk][k].val;
if (!store.count(temp)) {
f[i].push_back(temp);
if (abs(tar-temp.val) < abs(tar-ans.val)) ans = temp;
store[temp].p1 = f[jj][j];
store[temp].p2 = f[kk][k];
}
}
if (f[jj][j].val != 0 && f[kk][k].val%f[jj][j].val == 0) {
temp.val = f[kk][k].val/f[jj][j].val;
if (!store.count(temp)) {
f[i].push_back(temp);
if (abs(tar-temp.val) < abs(tar-ans.val)) ans = temp;
store[temp].p1 = f[jj][j];
store[temp].p2 = f[kk][k];
}
}
}
}
}
}
tot = 0;
if (store[ans].p1 != start || store[ans].p2 != start) {
tot++;
d[tot] = store[ans];
val[tot] = ans.val;
for (int i = 1; i <= tot; i++) {
if (store[d[i].p1].p1 != start) {
tot++;
d[tot] = store[d[i].p1];
val[tot] = d[i].p1.val;
}
if (store[d[i].p2].p1 != start) {
tot++;
d[tot] = store[d[i].p2];
val[tot] = d[i].p2.val;
}
}
}
printf("Target: %d\n", tar);
for (int i = tot; i >= 1; i--) {
// +
if (d[i].p1.val + d[i].p2.val == val[i]) {
printf("%d + %d = %d\n", d[i].p1.val, d[i].p2.val, val[i]);
continue;
}
// -
if (d[i].p1.val - d[i].p2.val == val[i]) {
printf("%d - %d = %d\n", d[i].p1.val, d[i].p2.val, val[i]);
continue;
}
if (d[i].p2.val - d[i].p1.val == val[i]) {
printf("%d - %d = %d\n", d[i].p2.val, d[i].p1.val, val[i]);
continue;
}
// *
if (d[i].p1.val * d[i].p2.val == val[i]) {
printf("%d * %d = %d\n", d[i].p1.val, d[i].p2.val, val[i]);
continue;
}
// /
if (d[i].p2.val != 0 && d[i].p1.val / d[i].p2.val == val[i]) {
printf("%d / %d = %d\n", d[i].p1.val, d[i].p2.val, val[i]);
continue;
}
if (d[i].p1.val != 0 && d[i].p2.val / d[i].p1.val == val[i]) {
printf("%d / %d = %d\n", d[i].p2.val, d[i].p1.val, val[i]);
continue;
}
}
printf("Best approx: %d\n", ans.val);
}
}