题目:P1013 [NOIP1998 提高组] 进制位
解题思路:
1:根据题干要求:9>=N>=3 , 且字母不重复,所以是2进制到8进制之间的数据
2:假设N=5,即输入四进制数据,则S(i,0)列必是:0,1,2,3;并作为每行的开头数字(行顺序可先不在意),每行简单的和每列数字做下加法如下:
1开头的行(10) 2开头的行(10,11) 3开头的行(10,11,12)
1+1 = 02 2+1 = 03 3+0 = 03
1+2 = 03 2+2 = 10 3+1 = 10
1+3 = 10 2+3 = 11 3+2 = 11
3+3 = 12
识别行开头的逻辑:根据上面规律发现行开头是数字n,则行内出现双位数的数量即n;反之出现了几个双位数就是几开头。
3:题干其他判断逻辑:
一:斜对角对称
二:第一列或第一行内容不重复
三:S[i,0]值 + S[0,j]值 = S[i,j] //S[i,j]字符根据位数做切割,并把十位字符数乘以进制数,再加上个位数值
编码解决:
-
- import java.util.*;
-
- public class Main {
-
-
- public static void main(String[] args) {
- run();
- }
-
- public static void run() {
- try { //初始化输入
- Scanner scanner = initScanner();
- //读取整数
- Integer n = readNumnber(scanner, 3, 9);
- //根据整数构建二维数组
- String[][] datas = read2Array(scanner, n);
- //统计 - 每个字符出现次数
- Map
rs = new LinkedHashMap<>(); -
- //校验数据行
- for (int i = 0; i < n; i++) {
- if (!datas[i][0].equals(datas[0][i])) {
- throw new RuntimeException("不对称");
- }
- if (datas[i][0].length() != 1) {
- throw new RuntimeException("字母长度不对");
- }
- //统计每个字母行内出现2位长度的字符数量,即当前行字符的数值
- int cnt = 0;
- for (int j = 0; j < n; j++) {
- if (datas[i][j].length() <= 1) {//2位数
- continue;
- }
- cnt++;
- }
- rs.put(datas[i][0], cnt + "");
- }
-
- //判断字符是否重复
- if (rs.keySet().size() != n) {
- throw new RuntimeException("数组高度重复");
- }
- //移除加号统计
- rs.remove("+");
-
- //替换二维数组字符 转 数字
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < n; j++) {
- if ("+".equals(datas[i][j])) {
- continue;
- }
- for (Map.Entry
entry : rs.entrySet()) { - datas[i][j] = datas[i][j].replaceAll("[" + entry.getKey() + "]", entry.getValue());
- }
- }
-
- if ("+".equals(datas[i][0])) {
- continue;
- }
-
- //数值不能超过进制最大值
- if (Integer.parseInt(datas[i][0]) > n - 2) {
- throw new RuntimeException("超出进制范围");
- }
- }
-
- //校验数据行
- for (int i = 1; i < n; i++) {
- for (int j = 1; j < n; j++) {
- //加法校验(n-1进制)
- if (datas[i][j].length() <= 1) {//单字符值校验
- if (Integer.parseInt(datas[i][0]) + Integer.parseInt(datas[0][j]) != Integer.parseInt(datas[i][j])) {
- throw new RuntimeException("进制加法不通过 n=" + (n - 1) + " i=" + i + ",j=" + j + " -> " + datas[i][j]);
- }
- } else {//双位字符值校验
- String[] ds = datas[i][j].split("");
- if (Integer.parseInt(datas[i][0]) + Integer.parseInt(datas[0][j]) != Integer.parseInt(ds[0]) * (n - 1) + Integer.parseInt(ds[1])) {
- throw new RuntimeException("进制加法不通过 n=" + (n - 1) + " i=" + i + ",j=" + j + " -> " + datas[i][j]);
- }
-
- }
- }
- }
-
- String text = rs.toString().replaceAll("[{}\"]", "").replaceAll(":", "=");
- text = text.replaceAll(",", "");
- System.out.println(text);
- System.out.print(n - 1);
- } catch (RuntimeException e) {
- //e.printStackTrace();
- System.out.print("ERROR!");
- }
- }
-
-
- public static Scanner initScanner() {
- return new Scanner(System.in);
- }
-
- //读取整数行
- public static int readNumnber(Scanner scanner, Integer min, Integer max) {
- int val = Integer.parseInt(scanner.nextLine());
- if (min != null && val < min) {
- throw new RuntimeException("数值" + val + "不能小于" + min);
- }
- if (max != null && val > max) {
- throw new RuntimeException("数值" + val + "不能大于" + max);
- }
- return val;
- }
-
- //输入读取二维数组
- public static String[][] read2Array(Scanner scanner, int arraySize) {
- String[][] datas = new String[arraySize][arraySize];
- for (int i = 0; i < arraySize; i++) {
- String line = scanner.nextLine();
- if (line == null || line.equals("")) {//如果是最后一行,使用next
- break;
- }
- String[] l = line.split(" ");
- if (l.length != arraySize) {
- throw new RuntimeException("数组长度不对");
- }
- datas[i] = l;
- }
- for (int i = 0; i < datas.length; i++) {
- for (int j = 0; j < datas[i].length; j++) {
- //System.out.print(datas[i][j] + " ");
- }
- //System.out.println("");
- }
- return datas;
- }
-
-
- }