首页 > 其他分享 >P1013 进制位 题解

P1013 进制位 题解

时间:2024-02-27 19:44:05浏览次数:22  
标签:进制 int 题解 P1013 mp str 加法 数字

题注

  • 题目传送门
  • 这篇题解其实是上一篇题解(Llf0703 同志)证明过程的完善(其实就是思路一样了啦),来让入门者或追求严谨者对证明过程更加了解。

题目分析

  1. \(3 \leq n \leq9\),也即数字的个数 \(N \leq 8\)。
  2. 研究样例发现,\(N\) 与进制 \(R\),以及数字对应两位数个数 \(M\) 与数字本身 \(S\) 具有

\[N = R, M = S \]

的关系,下面给出具体证明。


证明

1. 证:\(N = R\)。

  • 由题意可知,每个字母代表着不同的数字,所以 \(R \geq N\) 必然成立
  • 设加法表中每个数字分别为 \(a_i, i \in [0, N - 1]\)。
  • 若 \(R > N\),则存在有 \(k \in [0, R - 1]\),满足 \(k \ne a_i, i \in [0, N - 1]\)。
  • 因为在 \(R\) 进制下,二数相加最大可以达到 \(T\),而

\[\begin{aligned} T & = 2(R - 1) \\ & = R + (R - 2) \\ & = (1r)_R \end{aligned} \]

  • 其中 \(r = R - 2\)。
  • 例:在 3 进制下,\(T = (2)_3 + (2)_3 = (11)_3\)。
  • 所以一定会出现加法表中两数字相加等于 \(k\) 或等于 \((1k)_R\) 的情况,或者 \(k = 1\) 时加和等于 \((1x)_R, x \in [0, R - 2]\) 的情况,使得 \(k\) 出现在加法表上,这与 \(k \ne a_i, i \in [0, N - 1]\) 相矛盾,因此 \(R \ngtr N\)。
  • 而由题目分析可知,\(N = R\) 是可以成立的。
  • 因此,在加法表合法的情况下,\(N \equiv R\),证毕。

2. 证:\(M = S\)。

  • 由 1. 可知,\(N = R\),且加法表中最高为两位数
  • 因为只有在 \(S + x \geq R\) 时,\((S)_R + (x)_R\) 才能为两位数,且 \(x\) 为 \(R\) 进制下的数字,则可列出以下的不等方程组

\[\begin{cases} S + x \geq R \\ x \leq R - 1 \end{cases} \]

  • 解得方程解集为 \(x \in [R - S, R - 1]\)。
  • 所以 \(M = (R - 1) - (R - S) + 1 = S\),证毕。

结论

  • 因此,题目分析中的两个猜想都成立,我们以此为基础打出代码。
  • 先计算出每个字母所代表的数字(通过猜想 2),然后验证加法表是否匹配即可。

AC代码

#include <bits/stdc++.h>
using namespace std;
int n, S[13], mp[13];
char str[13][13][3];

bool add(int a, int b) {
	int sum = S[a] + S[b], ch = str[a][b][0] - 'A' + 1; //计算加和,取第一位
	if (sum >= n - 1) { //有进位时,高位一定为1
		if (strlen(str[a][b]) != 2 || mp[1] != ch) {
			return 0; //若str[a][b]不为两位数或者第一位不为1,返回错误
		} else {
			sum -= n - 1; //减掉高位,取低位
			ch = str[a][b][1] - 'A' + 1;
		}
	}
	if (mp[sum] != ch) {
		return 0; //不匹配则返回错误
	}
	return 1;
}

int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%s", str[1][i]);
	}
	int M;
	bool flag = 0;
	for (int i = 2; i <= n; i++) {
		M = 0;
		for (int l = 1; l <= n; l++) {
			scanf("%s", str[i][l]);
			if (strlen(str[i][l]) > 1) {
				M++; //计算两位数个数
			}
		}
		S[i] = M; //记录字母对应数字
		if (flag == 0 && mp[M]) { //查重
			flag = 1;
		}
		mp[M] = str[i][1][0] - 'A' + 1; //记录数字对应字母以查重
	}
	if (flag) { //重复错误
		printf("ERROR!");
		return 0;
	}
	for (int i = 2; i <= n; i++) {
		for (int l = 2; l <= n; l++) {
			if (add(i, l) == 0) { //加起来检验加法表是否匹配
				printf("ERROR!"); //不匹配错误
				return 0;
			}
		}
	}
	for (int i = 2; i <= n; i++) {
		printf("%c=%d ", str[i][1][0], S[i]);
	}
	printf("\n%d", n - 1);
	return 0;
}

标签:进制,int,题解,P1013,mp,str,加法,数字
From: https://www.cnblogs.com/iloveoi/p/18037701

相关文章

  • Pursuit For Artifacts 题解(图论)
    PursuitForArtifacts题解题目给定一张\(n\)个点\(m\)条边的简单无向连通图,边有边权,边权要么为\(0\),要么为\(1\)。每条边只能通过一次(两个方向加起来只能通过一次)。求是否存在一条从\(a\)到\(b\)的路径,满足路径上至少存在一条权为\(1\)的边。\(1\leqn,m\l......
  • CF1864C 题解
    \(x=2^k\)是好做的,每次以\(2^{k-1}\)为因数即可。对于其他情况,考虑每次让\(x\)减去其二进制下最低位的\(1\)直至变成\(2^k\)。这种策略下显然每个数只会在以上两个大步骤下取到,故每个数使用不超过\(2\)次。同时操作次数在\(O(\logn)\)这个量级。#include<bits/......
  • P7086 题解
    考虑把每个字符串的前\(k\)位和后\(k\)位看成点,字符串看成边,那么一个字符串前缀后缀至少有一个是相似群体的前缀后缀,看成这条边的两个端点至少有一个被选中。那么这就变成了一个最小点覆盖问题。考虑匈牙利算法算出答案,然后考虑如何构造答案。考虑右边没有被匹配的点,选中这......
  • AT_abc317_f 题解
    调了一小时结果发现爆longlong了。考虑数位dp,具体来说,设计状态\(dp_{i,r_1,r_2,r_3,mx_1,mx_2,mx3_,c_1,c_2,c_3}\)表示当前考虑到第\(i\)位,\(x_1,x_2,x_3\)模\(a_1,a_2,a_3\)等于\(r_1,r_2,r_3\)三个数是否达到\(n\)的上界以及是否全部是\(0\)。然后从高到低枚......
  • AT_joisc2019_j 题解
    先考虑这个式子:\[\sum_{j=1}^{M}|C_{k_{j}}-C_{k_{j+1}}|\]一定是在\(C\)有序时取到,具体证明很简单各位读者自己证明。那么现在式子变成:\[\sum{V}+2\times({C_{\max}-C_{\min}})\]这个时候一个常见的技巧是将\(C\)排序。这个时候就可以定义状态:\[dp_{i,j}=\s......
  • CF1862G 题解
    首先这个查询操作很迷,考虑先化简查询操作。不难发现由于每次是加上一个逆的等差序列,因此一次操作完每个数与它的前驱之差一定会减少,因此加上等差序列的次数就等于全局每个数与它的前驱之差最大值。又因为会排序去重,所以最后剩下来的数一定是最开始的数一路加过来的,至此我们发现......
  • P5837 [USACO19DEC] Milk Pumping G 题解
    原题传送门思路只用堆每一个点跑一边最短路,在用当前点到点\(n\)的距离,再用当前点的\(f\)乘上\(10^6\)除以刚刚算出的值即可。代码#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<queue>usingnamespacestd;#defin......
  • P2350 [HAOI2012] 外星人 题解
    很巧妙的一道题。首先会发现如果最终\(\varphi(N)=1\)的话一定是通过很多次从\(2\)这个因子变到\(1\)的。而这个函数每迭代一次,就会有且仅有一个\(2\)的因子变为\(1\)。所以题目转化为了求\(N\)在函数迭代过程中一共会产生多少个\(2\)的因子。考虑\(\text{dp}\),设......
  • U332154 carbon 题解(期望)
    这题其实挺简单的......首先我们手模样例,对于第一组样例其实就是在1-n之间取一个数,求取到的数的期望。所以E(x)=\(\frac{1+n}{2}\)。对于第二组样例,我们首先将所有可能情况枚举出来:1010101010101010101099999999910888888889......
  • U329011 trie pi 题解
    花了2d打磨出来的题目,觉得很有意思。先讲点无关的,这道题有两版,但都是对要求的量进行改动。1.第一次要求的是y属性为a与y属性为b的两个节点的路径权值之和,对于要求的这个量,我们设v[i]为i到根节点的权值之和。那么我们先对a,b进行质因数分解,设dcg为a,b分解质因数后最长公共前缀的乘......