您的位置:首页

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

2016-06-24 09:17 513 查看
题目链接: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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: