Codeforces Round #359 (Div. 2) C. Robbers' watch 搜索

题目链接:http://codeforces.com/contest/686/problem/C
题目大意:
给你两个十进制的数n和m,选一个范围在[0,n)的整数a,选一个范围在[0,m)的整数b,要求a的7进制表示和b的7进制表示中的每一位都不重复。其中,a的7进制位数和n-1的7进制位数相同,b的位数和m-1的位数相同。
比如,当n=2,m=3时,a和b的其进制表示的所有集合是:
a=0, b=1
a=0, b=2
a=1, b=0
a=1, b=2
解法:
这套题目可以用dfs做。
我们开一个数组f[],f[i]表示数字i有没有在a和b的七进制表示中出现过。
然后我们遍历a和b的每一位,如果在判断这个数的第i位的时候恰好f[i]=false,我们就可以将f[i]设为true,并将这一位的值设成i,然后继续搜索。
假设我们已经通过搜索得到了a,此时边有一个确定的a(a不是我们答案里需要的,但是我们搜索的过程中实际上会遍历得到所有合法的a)以及一个确定的f[]数组。此时按照dfs_m()函数求得b(b也不是答案里需要的),如果b合法,则ans++(ans是最终答案)。
dfs_m()函数如下(用它来得到b):

void dfs_m(int tmp, int tm) {
    if (tmp >= m) return;
    if (tm < 0) {
        ans ++;
        return;
    }
    for (int i = 0; i < maxn; i ++) {
        if (f[i] == false) {
            f[i] = true;
            dfs_m(tmp + i * g[tm], tm-1);
            f[i] = false;
        }
    }
}

我们已经有了dfs_m()了,那么只要我们在找b之前找到每一个a就行了,找a的方法也是dfs,如下的dfs_n()方法:

void dfs_n(int tmp, int tn) {
    if (tmp >= n) return;
    if (tn < 0) {
        dfs_m(0, mm-1);
        return;
    }
    for (int i = 0; i < maxn; i ++) {
        if (f[i] == false) {
            f[i] = true;
            dfs_n(tmp + i * g[tn], tn-1);
            f[i] = false;
        }
    }
}

完整代码:

 

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 7;
bool f[maxn];
int g[maxn], n, m, nn, mm;
long long ans = 0;
void init() {
    memset(f, false, sizeof(f));
    g[0] = 1;
    for (int i = 1; i < maxn; i ++)
        g[i] = g[i-1] * 7;
}
int chk(int n) {
    if (n == 1)
        return 1;
    n -= 1;
    int cnt = 0;
    while (n) {
        n /= 7;
        cnt ++;
    }
    return cnt;
}
void dfs_m(int tmp, int tm) {
    if (tmp >= m) return;
    if (tm < 0) {
        ans ++;
        return;
    }
    for (int i = 0; i < maxn; i ++) {
        if (f[i] == false) {
            f[i] = true;
            dfs_m(tmp + i * g[tm], tm-1);
            f[i] = false;
        }
    }
}
void dfs_n(int tmp, int tn) {
    if (tmp >= n) return;
    if (tn < 0) {
        dfs_m(0, mm-1);
        return;
    }
    for (int i = 0; i < maxn; i ++) {
        if (f[i] == false) {
            f[i] = true;
            dfs_n(tmp + i * g[tn], tn-1);
            f[i] = false;
        }
    }
}

int main() {
    scanf("%d%d", &n, &m);
    init();
    if (n > m) swap(n, m);
    nn = chk(n);
    mm = chk(m);
    if (nn + mm > 7) {
        puts("0");
        return 0;
    }
    dfs_n(0, nn-1);
    cout << ans << endl;
    return 0;
}

 

posted @ 2016-06-24 09:17  月光诗人  阅读(212)  评论(0编辑  收藏  举报