UVA - 10825 Anagram and Multiplication 暴力

来源:互联网 发布:java分销系统源码 编辑:程序博客网 时间:2024/06/11 12:44

题目大意:给出m和n,要求你求出一个m位的n进制数,这个数分别乘上1,2,..,m之后的值是这个数每位上的数的排列组合中的其中一种,求这个数

解题思路:这题的难点是怎么枚举这个数。因为要分别乘上1,2,..,m,如果我们枚举这个数的最后一位的话,乘上这些数后不然得出最后一位的值,而这些值必然是属于这个数的,只是不知道再那个位置上而已,所以要对这些数进行排列组合,然后再进行确认,确认的过程就是暴力的过程

#include<cstdio>#include<algorithm>#include<cstring>using namespace std;#define maxn 410int m, n, vis[maxn], tmp[10], ans[10], pos[10], cnt[maxn];bool ck() {int c[10];c[m] = 0;for(int i = 0; i < m; i++)ans[i] = c[i] = tmp[pos[i]];for(int i = 2; i <= m; i++) {for(int j = 0; j < m; j++) {c[j+1] += (c[j] + ans[j]) / n;c[j] = (c[j] + ans[j]) % n;}if(c[m])return false;for(int j = 0; j < m; j++)vis[c[j]]++;bool flag = false;for(int j = 0; j < m; j++)if(vis[c[j]] != cnt[c[j]])flag = true;for(int j = 0; j < m; j++)vis[c[j]]--;if(flag)return false;}return true;}bool dfs(int cur) {if(cur == m)return ck();for(int i = cur; i < m; i++){swap(pos[i],pos[cur]);if(dfs(cur+1))return true;swap(pos[i],pos[cur]);}return false;}bool check(int cur) {int t = 0;memset(vis,0,sizeof(vis));memset(cnt,0,sizeof(cnt));for(int i = 0; i < m; i++) {t = (t + cur) % n;tmp[i] = t;pos[i] = i; }for(int i = 0; i < m; i++)cnt[tmp[i]]++;return dfs(0);}int main() {while(scanf("%d%d", &m, &n) != EOF && m + n) {bool flag = false;for(int i = 1; i < n; i++) if(check(i)) {flag = true;break;}if(!flag)printf("Not found.\n");else{for(int i = m - 1; i > 0; i--)printf("%d ",ans[i]);printf("%d\n",ans[0]);}}return 0;}


0 0
原创粉丝点击