java|Java蓝桥杯——九宫幻方

题目描述: 三阶幻方指的是将1~9不重复的填入一个3*3的矩阵当中,使得每一行、每一列和每一条对角线的和都是相同的。例如:

4 9 2
3 5 7
8 1 6

有意思的是,所有的三阶幻方,都可以通过这样一个九宫格进行若干镜像和旋转操作之后得到。
输入输出: 输入:
输入仅包含单组测试数据。
输入的测试数据为一个3*3的矩阵,其中为0的部分表示被抹去的部分。
对于100%的数据,满足给出的矩阵至少能还原出一组可行的三阶幻方。
输出:
如果仅能还原出一组可行的三阶幻方,则将其输出,否则输出“Too Many”(不包含引号)。
详细代码: Java:

package easy; //import java.util.Date; import java.util.Scanner; public class Number_n { static int[] num = new int[10]; static int[] result = new int[10]; static boolean[] bool = new boolean[10]; static boolean[] flag = new boolean[10]; //初始输入九宫格中数字i是否被使用了 public static int count = 0; public static void main(String[] args) { Scanner input = new Scanner(System.in); for(int i = 1; i < 10; i++){ num[i] = input.nextInt(); flag[num[i]] = true; }f(1); input.close(); if(count == 1){ System.out.println(result[1]+ " " +result[2]+ " " +result[3]); System.out.println(result[4]+ " " + result[5]+ " "+result[6]); System.out.println(result[7]+ " " + result[8]+ " "+result[9]); } else if(count == 0) System.out.println("Zero!"); else System.out.println("Too Many!"); } public static void f(int step){ if(step == 10){ int a = num[1] + num[2] +num[3]; int b = num[4] + num[5] +num[6]; int c = num[7] + num[8] +num[9]; int d = num[1] + num[4] +num[7]; int e = num[2] + num[5] +num[8]; int f = num[3] + num[6] +num[9]; int g = num[1] + num[5] +num[9]; int h = num[3] + num[5] +num[7]; if(a==b && a==c && a==d && a==e && a==f && a==g && a==h){ for(int p = 1; p < 10; p++){ result[p] = num[p]; } count++; } else return; return; }if(num[step] != 0){ f(step+1); return; }for(int i = 1; i < 10; i++){//将数字1-9一次试着填入进为0的位置 if(!bool[i] && !flag[i] && num[step]==0){ bool[i] = true; //数字i此时已经被填入 num[step] = i; f(step+1); num[step] = 0; bool[i] = false; } } } }


C++:
#include int show(int *str,int *ch) { for(int j=0; j<9; j++) { if(str[j]==ch[j])continue; if(ch[j]==0)continue; if(str[j]!=ch[j])return 0; } return 1; } int main() { //1880: [蓝桥杯][2017年第八届真题]九宫幻方 /* 6 7 28 3 42 9 46 1 8 1 5 91 5 97 5 37 5 3 8 3 46 7 26 1 82 9 4 2 7 64 3 84 9 28 1 6 9 5 19 5 13 5 73 5 7 4 3 82 7 68 1 64 9 2 */ int str[][9]={ {6,7,2,1,5,9,8,3,4}, {8,3,4,1,5,9,6,7,2}, {2,9,4,7,5,3,6,1,8}, {6,1,8,7,5,3,2,9,4}, {2,7,6,9,5,1,4,3,8}, {4,3,8,9,5,1,2,7,6}, {4,9,2,3,5,7,8,1,6}, {8,1,6,3,5,7,4,9,2}, }; int ch[9]; for(int i=0; i<3; i++) { for(int j=0; j<3; j++) scanf("%d",&ch[i*3+j]); } int i,tmp=0; for(int k=0; k<8; k++) { if(show(str[k],ch)) { tmp+=1; if(tmp==1)i=k; } } if(tmp==1) for(int j=0; j<9; j++) { if(j!=0 &&j%3==0) printf("\n"); printf("%d ",str[i][j]); } else{ printf("Too Many"); } return 0; }

解决思路: 上面Java与C++两种语言不同的代码,正好是两种不同的解题思路
Java:
回溯法思想,一点一点判断,不对则进行回溯修改

【java|Java蓝桥杯——九宫幻方】C++:
将所有可能的结果存在数组中,将输入进来的九宫格和所有可能的结果一一进行比较

    推荐阅读