[NOIP1998 提高组] 进制位 题解

题目

其实这个题只要知道他是 n n n 进制的,就可以轻松写出暴力代码。

因为它有 n n n 个不同的数,而如果是 n + 1 n + 1 n+1 进制就会有一些数不能用给定字母表示出来,如果是 n − 1 n - 1 n1 进制就会有两个数是一样的,但是题目要求任意两数都不相同。

理解了为什么是 n n n 进制后,就可以打出暴力代码。

可以枚举每一个数分别是什么,用 next_premutation,再判断其正确性,如果每一个加法结果都正确,就输出结果,走人。如果判断到最后还没有找到,就输出ERROR!,由于 3 ≤ n ≤ 9 3 \le n \le 9 3n9,所以可以将加法结果当成一个 n n n 进制数处理,但是还是用的int类型,操作时细节比较多,务必注意。

AC Code:

#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <set>
#include <map>
using namespace std;
int n;
string s[20][20];
map<char, int> m;
int ans[10];
int change(string str) {
	int len = str.size();
	int ret = 0;
	for (int i = 0; i < len; i ++) {
		ret *= (n - 1);
		ret += ans[m[str[i]]];
	}
	int a1 = ret % (n - 1);
	int a2 = ret / (n - 1);
	return a2 * 10 + a1;
}
bool check(int i, int j) {
	int tmp = change(s[i][j]);
	int a1 = (ans[i] + ans[j]) % (n - 1);
	int a2 = (ans[i] + ans[j]) / (n - 1);
	if (a2 * 10 + a1 == tmp) return 1;
	else return 0;
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i ++) {
		for (int j = 1; j <= n; j ++) {
			cin >> s[i][j];
		}
	}
	for (int i = 1; i <= n; i ++) {
		m[s[i][1][0]] = i;
	}
	for (int i = 2; i <= n; i ++) {
		ans[i] = i - 2;
	}
	do {
		bool flag = 0;
		for (int i = 2; i <= n; i ++) {
			for (int j = 2; j <= n; j ++) {
				if (!check(i, j)) flag = 1;
			}
		}
		if (flag == 0) {
			for (int i = 2; i <= n; i ++) {
				cout << s[i][1] << '=' << ans[i] << ' ';
			}
			cout << '\n' << n - 1;
			return 0;
		}
	} while (next_permutation(ans + 2, ans + 1 + n));
	cout << "ERROR!";
	return 0;
}
  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值