POJ 3932 Matches

来源:互联网 发布:怎么做淘宝客漏洞赚钱 编辑:程序博客网 时间:2024/06/07 11:26

http://poj.org/problem?id=3932

动态规划:

创建数组dp_state[i][j][k]。其中i代表保存从A[0…i]+B[0…i]==C[0…i]

j取值[03],其含义分别为:

l j==0,0i无火柴移动

l j==1,0i拿走一根火柴

l j==2, 0i数位移入一根火柴

l j==3, 0i数位中一根火柴被移动且放入该数位区间。

k=01代表了A[i]+B[i] + carry>= 10, 如果10 <= A[i]+B[i]+carry,则k=1代表需向前进位。

设函数F(I,J,carry)代表j取值[0,3]时,在A[i],B[i],C[i]对应数位操作可否让(A[i]+B[i]+carry)%10==C[i]成立

DP状态转移方程如下

dp_state[i][0][0] ={ (dp_state [i-1][0][0]&&F(I,0,0)

|| (dp_state [i-1][0][0]&&F(I,0,1))

&& A[i]+B[i]+carry < 10}

dp_state[i][0][1] = {(dp_state [i-1][0][0]&&F(I,0,0)

|| (dp_state [i-1][0][0]&&F(I,0,1))

&& A[i]+B[i]+carry >= 10}

类似可推导dp_state[i][j][k]其余对应转移.

#include <iostream>#include <vector>#include <cmath>#include <cstdlib>#include <cstdio>#include <cstring>#include <queue>#include <algorithm>using namespace std;/************************************************************************/void  move_to_other(int deep,bool had, int* n, int op, int pos, int s,int preop, int one = 0);bool  unchange_add(int pos, int s, int preop, int one = 0);void  move_to_orgin(int deep, int op, int* n, int pos, int s, int preop, int one = 0);void print_ans(int mn);/************************************************************************/struct Point {int x,y;};#define BUFSIZE 100010struct  State {int n[3];int op;bool is_ok;State() {n[2] = n[1]= n[0] = 0;op = -1;is_ok = false;}void reset() {n[2] = n[1]= n[0] = 0;op = -1;is_ok = false;}};State dp_state[BUFSIZE][4][2];vector<int> convert_n[10][3];string num[3];string ans_num[3];char buf[BUFSIZE];void init() {//0->change one stick, remove stick, add stickconvert_n[0][0].push_back(0);convert_n[0][0].push_back(6);convert_n[0][0].push_back(9);convert_n[0][2].push_back(8);convert_n[1][0].push_back(1);convert_n[1][2].push_back(7);convert_n[2][0].push_back(2);convert_n[2][0].push_back(3);convert_n[3][0].push_back(3);convert_n[3][0].push_back(2);convert_n[3][0].push_back(5);convert_n[3][2].push_back(9);convert_n[4][0].push_back(4);convert_n[5][0].push_back(5);convert_n[5][0].push_back(3);convert_n[5][2].push_back(6);convert_n[5][2].push_back(9);convert_n[6][0].push_back(6);convert_n[6][0].push_back(0);convert_n[6][0].push_back(9);convert_n[6][1].push_back(5);convert_n[6][2].push_back(8);convert_n[7][0].push_back(7);convert_n[7][1].push_back(1);convert_n[8][0].push_back(8);convert_n[8][1].push_back(0);convert_n[8][1].push_back(6);convert_n[8][1].push_back(9);convert_n[9][0].push_back(9);convert_n[9][0].push_back(0);convert_n[9][0].push_back(6);convert_n[9][1].push_back(3);convert_n[9][1].push_back(5);convert_n[9][2].push_back(8);}void  move_to_orgin(int deep, int op, int* n, int pos, int s, int preop, int one/* = 0*/) {//op 1有移入matches -1,移走 matchesif (deep == 3) {if (0x03 != op)return;bool res = (n[2] == ((n[0] + n[1] + one)%10));int carry = (n[0]+n[1]+one)/10;if (res) {dp_state[pos][s][carry].is_ok = true;dp_state[pos][s][carry].op = preop;memcpy(dp_state[pos][s][carry].n, n, sizeof(int)*3);}return;} else {if (pos < num[deep].length()) {int v = num[deep][pos] - '0';int new_op = 0;if ((op&0x1) == 0) {for (int i = 0;  i < convert_n[v][1].size(); ++i) {n[deep] = convert_n[v][1][i];new_op = (op|0x1);move_to_orgin(deep + 1, new_op, n, pos, s, preop, one);}} if ((op&0x2) == 0) {for (int i = 0;  i < convert_n[v][2].size(); ++i) {n[deep] = convert_n[v][2][i];new_op = (op|0x2);move_to_orgin(deep + 1, new_op, n, pos, s, preop, one);}}if ((0 == op)) {for (int i = 0; i < convert_n[v][0].size(); ++i) {n[deep] = convert_n[v][0][i];new_op = 0x3;move_to_orgin(deep + 1, new_op, n, pos, s,preop, one);}}n[deep] = v;move_to_orgin(deep + 1, op, n, pos, s,preop, one);} else {n[deep] = 0;move_to_orgin(deep + 1, op, n, pos, s, preop, one);}}}void  move_to_other(int deep,bool had, int* n, int op, int pos, int s,int preop, int one/* = 0*/) {//op = 1, 2if (deep == 3) {if (false == had)return;bool res = (n[2] == (n[0] + n[1] + one)%10);int carry = (n[0]+n[1]+one)/10;if (res) {dp_state[pos][s][carry].is_ok = true;dp_state[pos][s][carry].op = preop;memcpy(dp_state[pos][s][carry].n, n, sizeof(int)*3);}return;} else {if (pos < num[deep].length()) {int v = (int)(num[deep][pos] - '0');if (!had) {for (int i = 0;  i < convert_n[v][op].size(); ++i) {n[deep] = convert_n[v][op][i];move_to_other(deep + 1, true, n, op, pos, s, preop, one);}}n[deep] = v;move_to_other(deep + 1, had, n, op, pos, s, preop, one);} else {n[deep] = 0;move_to_other(deep + 1, had, n, op, pos, s, preop, one);}}return ;}bool  unchange_add(int pos, int s, int preop, int one/* = 0*/) {int n[3] = {0};for (int i = 0; i < 3; ++i) {if (pos < num[i].length())  {n[i] = (int)(num[i][pos] - '0');}}bool res = (n[2] == (n[0] + n[1] + one)%10);if (res) {int carry = (n[0]+n[1] + one)/10;dp_state[pos][s][carry].is_ok = true;dp_state[pos][s][carry].op = preop;memcpy(dp_state[pos][s][carry].n, n, sizeof(int)*3);}return res;}void dp_solve() {int mn = 0;for (int i = 0; i < 3; ++i) {reverse(num[i].begin(), num[i].end());if (mn < num[i].length()) {mn = num[i].length();}}for (int i = 0; i < mn; ++i) {for (int j = 0; j < 4; ++j) {for (int k = 0; k < 2; ++k) {dp_state[i][j][k].reset();}}}for (int i = 0; i < mn; ++i) {if (0 == i) {unchange_add(0,0, 0);int n[3] = {0};move_to_other(0, false,n, 1, 0, 1, 0, 0);move_to_other(0, false,n, 2, 0, 2, 0, 0);move_to_orgin(0, 0, n, 0, 3, 0);} else {int n[3] = {0};//case j ==0if (dp_state[i-1][0][0].is_ok) {unchange_add(i, 0, 0, 0);move_to_other(0, false, n, 1, i, 1, 0, 0);move_to_other(0, false, n, 2, i, 2, 0, 0);move_to_orgin(0, 0, n, i, 3, 0, 0);}if (dp_state[i-1][0][1].is_ok) {unchange_add(i, 0, 0, 1);move_to_other(0, false, n, 1, i, 1, 4, 1);move_to_other(0, false, n, 2, i, 2, 4, 1);move_to_orgin(0, 0, n, i, 3, 4, 1);}for (int j = 1; j <= 3; ++j) {if (dp_state[i-1][j][0].is_ok) {unchange_add(i, j, j, 0);}if (dp_state[i-1][j][1].is_ok) {unchange_add(i, j, 4 + j, 1);}}if (dp_state[i-1][1][0].is_ok) {move_to_other(0, false, n, 2, i, 3, 1, 0);}if (dp_state[i-1][1][1].is_ok) {move_to_other(0, false, n, 2, i, 3, 5, 1);}if (dp_state[i-1][2][0].is_ok) {move_to_other(0, false, n, 1, i, 3, 2, 0);}if (dp_state[i-1][2][1].is_ok) {move_to_other(0, false, n, 1, i, 3, 6, 1);}}}print_ans(mn);}void insert_ans(int pos, int n[]) {for (int i = 0; i < 3; ++i) {if (pos < num[i].length()) {ans_num[i].append(1, n[i] + '0');}}}void print_ans(int mn) {int preop = -1;for (int i = mn - 1; 0 <= i; --i) {if (i == (mn - 1)) {preop = dp_state[mn-1][3][0].op;insert_ans(mn-1, dp_state[mn-1][3][0].n);} else {int j = preop%4;int k = preop/4;preop = dp_state[i][j][k].op;insert_ans(i, dp_state[i][j][k].n);}}printf("%s + %s = %s\n", ans_num[0].c_str(), ans_num[1].c_str(), ans_num[2].c_str());printf("*****************\n");}void reset_init() {for (int i = 0; i < 3; ++i) {num[i].clear();ans_num[i].clear();}}int main() {char c;int cur_idx = 0;init();while (gets(buf)) {int len = strlen(buf);for (int i = 0; i < len; ++i) {char c = buf[i];if ('0' <= c && c <= '9') {num[cur_idx].append(1,c);} else {if (' ' == c && num[cur_idx].length() > 0){cur_idx = (cur_idx + 1) % 3;}}}cur_idx = 0;dp_solve();reset_init();}}