P1013 [NOIP1998 提高组] 进制位

传送门

题意:

给你一个由字母代表数字的加法表,问你这个加法是几进制以及每个字母所代表的数字是多少。

思路:

动手稍微模拟一下就会发现:
1.表中一定会有进位。当表中有数字x时,那就一定会有数字x2,x4…一直到出现进位。
2.由于第一列和第一行的字符串长度都为1,那么可以的到这个表一定是n-1进制的。还是基于第一点,结合加法表和进位的特点,可以得到:最终一定会出现0到n-1的所有数。
所以只需要先找到0,再找到1,就可以推出后面的字母了。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
#define pb push_back 
#define p push
const int mod = 998244353;
string s[20][20];
char vis[200];
int pos[200];
int ans[20][20];
int num[200];

int main()
{
	int n;
	cin>>n;
	for(int i = 1; i <= n; i++)
	{
		for(int j = 1; j <= n; j++)
		{
			cin>>s[i][j];
		}
	}
	int flag = 0;
	for(int j = 2; j <= n; j++)
	{
		if(s[j][j] == s[1][j])
		{
			vis[0] = s[j][j][0];
			pos[s[j][1][0]] = j;
			num[s[j][1][0]] = 0;
		}
	}
	for(int i = 1; i <= n; i++)
	{
		for(int j = 1; j <= n; j++)
		{
			if(s[i][j].size() == 2)
			{
				if(s[i][j][1] == vis[0])
				{
					vis[1] = s[i][j][0];
					num[s[i][j][0]] = 1;
					flag = 1;
				}
			}
		}
	}
	for(int i = 2; i <= n; i++)
	if(s[1][i][0] == vis[1])pos[vis[1]] = i;
	if(!flag)
	{
		cout<<"ERROR!";
		return 0;
	}
	for(int i = 2; i < n-1; i++)
	{
		int f = 0;
		for(int j = 2; j <= n; j++)
		{
			if(num[s[1][j][0]] + 1== i)
			{
				f = 1;
				pos[s[pos[vis[1]]][j][0]] = j;
				num[s[pos[vis[1]]][j][0]] = i;
				vis[i] = s[pos[vis[1]]][j][0]; 
			}
		}
		if(!f)
		{
			cout<<"ERROR!";
			return 0;
		}
	}
	flag = 0;
	for(int i = 1; i <= n; i++)
	{
		for(int j = 1; j <= n; j++)
		{
			if(i==1 || j==1)continue;
			ans[i][j] = num[s[1][j][0]]+num[s[i][1][0]];
			int sum = 0;
			for(int k = 0; k < s[i][j].size(); k++)
			{
				sum = sum*(n-1)+num[s[i][j][k]];
			}
			if(sum!=ans[i][j])
			{
				cout<<"ERROR!";
				return 0;
			}
		}
	}
	for(int i = 2; i <= n; i++)
	{
		cout<<s[1][i]<<"="<<num[s[1][i][0]]<<" ";
	}
	cout<<endl<<n-1<<endl;
}
 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值