SDUT 周赛 2495 The Clocks DFS

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]);
    }
}

  

posted @ 2012-12-03 18:21  E_star  阅读(259)  评论(0)    收藏  举报