UVa 656 - Optimal Programs (DFSID + 模拟 + 枚举)
2014-10-18 10:46
357 查看
题意
给出五个操作,和两个序列。要求输出一种操作,使得从上一个序列的每个数可以变到下一个序列的每个数。
输出最小的操作数,如果相同,输出字典序最小的。
思路
没想到什么好的办法,暴力判断每一种操作,并记录如果操作过后就是后来的那个数,然后对这个操作检查之后的所有数,如果都满足,输出。
因为感觉BFS会超内存,就用了DFSID
因为我是按照字典序来依次执行操作的,所以当有合适的操作时候他一定是字典序最小的。
代码
#include <cstdio>
#include <stack>
#include <set>
#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <functional>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <string>
#include <map>
#include <cmath>
#define LL long long
#define SZ(x) (int)x.size()
#define Lowbit(x) ((x) & (-x))
#define MP(a, b) make_pair(a, b)
#define MS(arr, num) memset(arr, num, sizeof(arr))
#define PB push_back
#define F first
#define S second
#define ROP freopen("input.txt", "r", stdin);
#define MID(a, b) (a + ((b - a) >> 1))
#define LC rt << 1, l, mid
#define RC rt << 1|1, mid + 1, r
#define LRT rt << 1
#define RRT rt << 1|1
#define BitCount(x) __builtin_popcount(x)
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
using namespace std;
const int MAXN = 150 + 10;
const int MOD = 1e9 + 7;
const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
typedef pair<int, int> pii;
typedef vector<int>::iterator viti;
typedef vector<pii>::iterator vitii;
string comd, str[] = {"ADD", "DIV", "DUP", "MUL", "SUB"};
int n, ori[MAXN], fin[MAXN];
bool flag;
int Fun(int cmd, stack<int> &stk)
{
if (SZ(stk) == 1 && cmd != 2) return -1;
if (cmd == 0) //ADD
{
int a = stk.top(); stk.pop();
if (abs(a + stk.top()) > 30000)
{
stk.push(a);
return -1;
}
stk.top() += a;
}
else if (cmd == 1) //DIV
{
if (stk.top() == 0) return -1;
int a = stk.top(); stk.pop();
stk.top() /= a;
}
else if (cmd == 2) //DUP
stk.push(stk.top());
else if (cmd == 3) //MUL
{
int a = stk.top(); stk.pop();
if (abs(a * stk.top()) > 30000)
{
stk.push(a);
return -1;
}
stk.top() *= a;
}
else
{
int a = stk.top(); stk.pop();
if (abs(stk.top() - a) > 30000)
{
stk.push(a);
return -1;
}
stk.top() -= a;
}
return 0;
}
bool Check(string cmd)
{
for (int i = 1; i < n; i++)
{
stack<int> stk;
stk.push(ori[i]);
for (int j = 0; j < SZ(cmd); j++)
{
int tmp = Fun(cmd[j] - '0', stk);
if (tmp == -1) return false;
}
if (!(SZ(stk) == 1 && stk.top() == fin[i])) return false;
}
return flag = true;
}
void Goback(int fst, int sec, stack<int> &stk, int cmd)
{
if (cmd == 2) //DUP
stk.pop();
else
{
stk.pop();
stk.push(sec);
stk.push(fst);
}
}
bool DFS(int cnt, string comd, stack<int> stk, int step)
{
if (cnt > step) return false;
int fst = stk.top(); stk.pop();
int sec = INF;
if (!stk.empty()) sec = stk.top();
stk.push(fst);
for (int i = 0; i < 5; i++)
{
int tmp = Fun(i, stk);
if (tmp == -1) continue; //此操作不合法
char tempStr = i + '0';
if (SZ(stk) == 1 && stk.top() == fin[0]) //此操作过后可以转换
if (Check(comd + tempStr))
{
comd += tempStr;
for (i = 0; i < SZ(comd); i++)
if (i == 0) cout << str[comd[i] - '0'];
else cout << " " << str[comd[i] - '0'];
puts("");
return true;
}
if (DFS(cnt + 1, comd + tempStr, stk, step)) return true;
Goback(fst, sec, stk, i); //回到开始情况
}
return false;
}
int main()
{
//ROP;
int i, j, cases = 0;
while (scanf("%d", &n), n)
{
printf("Program %d\n", ++cases);
flag = false;
for (i = 0; i < n; i++) scanf("%d", &ori[i]);
for (i = 0; i < n; i++) scanf("%d", &fin[i]);
if (ori[0] == fin[0]) //先排除一下无操作的情况
{
for (i = 1; i < n; i++)
if (ori[i] != fin[i]) break;
if (i == n)
{
puts("Empty sequence");
puts("");
continue;
}
}
for (int step = 2; step <= 10; step++)
{
if (flag) break;
stack<int> stk; stk.push(ori[0]);
DFS(1, "", stk, step);
}
if (!flag) puts("Impossible");
puts("");
}
return 0;
}
相关文章推荐
- UVALive 6269 Digital Clock --枚举,模拟
- UVA 1508 - Equipment 状态压缩 枚举子集 dfs
- poj 1950 Dessert(dfs枚举,模拟运算过程)
- uva 11464 Even Parity 模拟 二进制枚举
- uva 10422 - Knights in FEN ID+dfs
- uva12558(埃及分数--难)(IDDFS入门题)
- UVA - 146 ID Codes (枚举排列)
- UVa 10717 Mint (DFS枚举4个数的lcm)
- UVA 1508 - Equipment 状态压缩 枚举子集 dfs
- UVA 387 A Puzzling Problem(dfs + 模拟)
- UVA - 10317 Equating Equations(普通的暴力枚举 dfs枚举 c(n,m))
- UVALive 6432 In uence(枚举+dfs或记忆化搜索+bitset)
- Uva725 Division【dfs枚举】【例题7-1】
- UVA - 11181 Probability|Given(条件概率+dfs枚举组合)
- hdu 4431 Mahjong (模拟,枚举+dfs)
- IDDFS--UVA - 1374 Power Calculus
- UVA Chinese Mahjong(暴力枚举+模拟)
- UVALive 6257 Chemist's vows --一道题的三种解法(模拟,DFS,DP)
- UVA - 131 The Psychic Poker Player (暴力枚举+模拟)
- UVA12558->IDDFS