UVA - 10825 Anagram and Multiplication 暴力

题目大意:有些m位n进制整数非常神奇,乘以2,3,4,..m之后,所得到的数恰好是原数个数字的一个排列,给出m和n,你的任务是保证是否有这样的一个数

解题思路:枚举最后一位,只要知道了最后一位就可以知道其他位的,因为是要乘于2到m的,所以假设最后一位是j的话,那么倒数第2位一定是(j+j)%n,倒数第三位是(j+j+j)%m,由此可以得到,现在只要判断一下所给的数经过计算后是否是原来各数字的一个排列即可

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 410
int tmp[10], ans[10], pos[10], vis[maxn], cnt[maxn], n, m;
bool ck() {
	int c[10];
	for(int i = 0; i < m; i++)
		c[i] = ans[i] = tmp[pos[i]];
	c[m] = 0;
	for(int k = 2; k <= m; k++) {
		for(int i = 0; i < m; i++) {
			c[i+1] += (c[i] + ans[i]) / n;
			c[i] = (c[i] + ans[i]) % n;	
		}	

		if(c[m])
			return false;
		bool flag = false;
		for(int i = 0; i < m; i++)
			vis[c[i]]++;
		for(int i = 0; i < m; i++)
			if(cnt[c[i]] != vis[c[i]])
				flag = true;
		for(int i = 0; i < m; i++)
			vis[c[i]] = 0;
		if(flag)
			return false;
	}
	return true;
}

bool dfs(int cur) {
	if(cur == m)
		return ck();
	for(int i = cur; i < m; i++) {
		swap(pos[cur],pos[i]);
		if(dfs(cur+1))
			return true;
		swap(pos[cur],pos[i]);	
	}
	return false;
}

bool check(int cur) {
	int t = 0;
	for(int i = 0; i < m; i++) {
		t = (t + cur) % n;
		tmp[i] = t;
		pos[i] = i;	
	}
	memset(vis,0,sizeof(vis));
	memset(cnt,0,sizeof(cnt));
	for(int i = 0; i < m; i++)
		cnt[tmp[i]]++;
	return dfs(0);
}
int main() {
	while(scanf("%d%d",&m, &n) == 2 && n + m) {
		bool flag = false;
		for(int i = 1; i < n; i++) 
			if(check(i)) {
				flag = true;
				break;	
			}
		if(!flag)
			printf("Not found.\n");
		else {
			printf("%d",ans[m-1]);
			for(int i = m - 2; i >= 0; i--)
				printf(" %d", ans[i]);
			printf("\n");	
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值