• 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;
    }
  • 相关阅读:
    Unity3D Editor模式下批量修改prefab
    3D touch在Unity3D中的使用
    Unity中的协程是什么?
    Unity3D脚本调用Objective C代码实现游戏内购买
    WindowsPhone8拍照功能实现简介
    WindowsPhone App如何扩展能够使用的内存
    SVN 提交代码时提示文件已经存在解决办法
    iOS检查App新版本并更新新版本
    iOS存储数据字典到沙盒
    统计整个Xcode工程代码行数
  • 原文地址:https://www.cnblogs.com/moonlightpoet/p/5613075.html
Copyright © 2020-2023  润新知