http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2495
题意:
给定一个3*3的矩阵,矩阵里面的数字的取值为3,6,9,12 。我们有9中操作,可以使举证中一些数字+3 ,问通过这九种操作我们能够用最少的操作数的序列,使得矩阵中的数字全部变成12.如果存在相同的则取字典序最小的。
思路:
才开始脑子转不过来,不知道怎么搜。。最后想了想,数字是以3的倍数增加的,每操作3次对应的数字又会回到原来的状态。所以我们只要枚举每种操作的次数。每种操作可以取0,1,2,3次这样的时间复杂度就是O(4^9)次方了。注意要对数字对12取余。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <set> #include <map> #include <string> #define CL(a,num) memset((a),(num),sizeof(a)) #define iabs(x) ((x) > 0 ? (x) : -(x)) #define Min(a,b) (a) > (b)? (b):(a) #define Max(a,b) (a) > (b)? (a):(b) #define ll __int64 #define inf 0x7f7f7f7f #define MOD 1073741824 #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define test puts("<------------------->") #define maxn 100007 #define M 500007 #define N 10007 #define K 1007 using namespace std; //freopen("din.txt","r",stdin); int mk[10][5] = { {0,0,0,0,0}, {1,2,4,5,0}, {1,2,3,0,0}, {2,3,5,6,0}, {1,4,7,0,0}, {2,4,5,6,8}, {3,6,9,0,0}, {4,5,7,8,0}, {7,8,9,0,0}, {5,6,8,9,0} }; int ans[30],tmp[30]; int ansL; int a[15]; int len; bool isok() { int i; for (i = 1; i <= 9; ++i) { if (a[i] != 0) return false; } return true; } void dfs(int pos) { int i,j; for (i = 1; i <= 9; ++i) a[i] %= 12; if (isok()) { if (ansL > len) { ansL = len; for (i = 0; i < len; ++i) ans[i] = tmp[i]; } else if (ansL == len) { for (i = 0; i < len; ++i) { if (ans[i] > tmp[i]) break; } if (i < len) { for (i = 0; i < len; ++i) ans[i] = tmp[i]; } } return; } else { if (pos > 9) return; for (i = 0; i <= 3; ++i) { for (j = 0; j < 5; ++j) a[mk[pos][j]] += 3*i; for (j = 0; j < i; ++j) tmp[len++] = pos; dfs(pos + 1); for (j = 0; j < i; ++j) len--; for (j = 0; j < 5; ++j) a[mk[pos][j]] -= 3*i; } } } int main() { //freopen("din.txt","r",stdin); int i; while (~scanf("%d",&a[1])) { for (i = 2; i <= 9; ++i) scanf("%d",&a[i]); CL(ans,0); CL(tmp,0); ansL = inf; len = 0; dfs(1); for (i = 0; i < ansL - 1; ++i) printf("%d ",ans[i]); printf("%d\n",ans[i]); } }