题目: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<String, String> 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<String, String> 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;
}
}