(A卷,100分)- 幻方修复(Java & JS & Python)

题目描述

幻方(Magic Square)是一个由1~N²,共N²个整数构成的N*N矩阵,满足每行、列和对角线上的数字和相等。

上回你已经帮助小明将写错一个数字的幻方进行了修复,小明在感谢之余也想进一步试试你的水平,于是他准备了有两个数字发生了位置交换的幻方。

你可以把这两个交换的数字找出来并且改正吗?

输入描述

第一行输入一个整数N,代表带校验幻方的阶数(3 ≤ N < 50)

接下来的N行,每行N个整数,空格隔开(1 ≤ 每个整数 ≤ N²)

输出描述

输出两行,代表两条纠正信息,注意先输出行号小的,若行号相同则先输出列好小的

每行输出空格隔开的三个整数,分别是:出错行号、出错列号、应填入的数字(末尾无空格)

用例

输入 3
8 1 9
3 5 7
4 6 2
输出 1 3 6
3 2 9
说明

题目解析

本题如果硬解的话,则逻辑上很简单,即:暴力枚举出所有的两点组合,并尝试交换,验证交换后的幻方的各行、各列、各对角线的和是否相等,若相等即找到了交换的两个点。

但是上面逻辑非常容易超时,因为暴力枚举两点组合的话,最多有2500 * 2499个组合,每个组合又要验证50条行和、50条列和,2条对角线和是否相等,当然这个过程中如果发现不相等的可以立即结束当前两点组合的验证。

在和网友讨论后,本题是有最佳解题策略的,这个策略和幻方的一个特性有关:

幻方中每一条直线上的数的和叫作幻和。

幻和 = 所有数的和 ÷ 阶数

当我们知道幻和后,就可以很轻易找出发生交换的两个点所在的行列,比如用例1中,我们遍历所有行、所有列后,可以得出不正确的行、列(即行和或列和不等于幻和的行、列)

 此时这些行、列的相交点,其实就可能是发生交换的点,

如下图标黄的点

 我们只需要尝试在这四个点中,进行两点组合选取,来尝试复原即可。

当然,我们还需要考虑一种特殊情况,比如下面图示中,发生交换的两个点处于同一行中,

 那么此时其实只有不正确列,没有不正确的行,即所有行和都是等于幻和的。

此时就没有所谓的“相交点”了,如下图所示

 此时,我们只能尝试用这两个不正确的列和所有行进行相交,然后进行同行两点组合,然后尝试交换

如果发生交换的两个点处于同一列中,和上面同理。

四阶幻方

4
1 8 11 14
12 13 2 7
6 3 16 9
15 10 5 4

五阶幻方

5
2 23 16 10 14
20 9 12 3 21
13 1 25 19 7
24 17 8 11 5
6 15 4 22 18

六阶幻方

6
21 23 4 1 32 30
22 24 2 3 31 29
28 27 17 18 9 12
25 26 19 20 11 10
8 6 34 36 13 14
7 5 35 33 15 16

七阶幻方

7
46 15 40 9 34 3 28
21 39 8 33 2 27 45
38 14 32 1 26 44 20
13 31 7 25 43 19 37
30 6 24 49 18 36 12
5 23 48 17 42 11 29
22 47 16 41 10 35 4

八阶幻方

8
64 2 62 4 5 59 7 57
9 55 11 53 52 14 50 16
48 18 46 20 21 43 23 41
25 39 27 37 36 30 34 32
33 31 35 29 28 38 26 40
24 42 22 44 45 19 47 17
49 15 51 13 12 54 10 56
8 58 6 60 61 3 63 1

九阶幻方

9
47 58 69 80 1 12 23 34 45
57 68 79 9 11 22 33 44 46
67 78 8 10 21 32 43 54 56
77 7 18 20 31 42 53 55 66
6 17 19 30 41 52 63 65 76
16 27 29 40 51 62 64 75 5
26 28 39 50 61 72 74 4 15
36 38 49 60 71 73 3 14 25
37 48 59 70 81 2 13 24 35

十阶幻方

10
92 99 1 8 15 67 74 51 58 40
98 80 7 14 16 73 55 57 64 41
4 81 88 20 22 54 56 63 70 47
85 87 19 21 3 60 62 69 71 28
86 93 25 2 9 61 68 75 52 34
17 24 76 83 90 42 49 26 33 65
23 5 82 89 91 48 30 32 39 66
79 6 13 95 97 29 31 38 45 72
10 12 94 96 78 35 37 44 46 53
11 18 100 77 84 36 43 50 27 59

二十阶幻方

20
400 2 398 4 396 6 394 8 392 10 11 389 13 387 15 385 17 383 19 381
21 379 23 377 25 375 27 373 29 371 370 32 368 34 366 36 364 38 362 40
360 42 358 44 356 46 354 48 352 50 51 349 53 347 55 345 57 343 59 341
61 339 63 337 65 335 67 333 69 331 330 72 328 74 326 76 324 78 322 80
320 82 318 84 316 86 314 88 312 90 91 309 93 307 95 305 97 303 99 301
101 299 103 297 105 295 107 293 109 291 290 112 288 114 286 116 284 118 282 120
280 122 278 124 276 126 274 128 272 130 131 269 133 267 135 265 137 263 139 261
141 259 143 257 145 255 147 253 149 251 250 152 248 154 246 156 244 158 242 160
240 162 238 164 236 166 234 168 232 170 171 229 173 227 175 225 177 223 179 221
181 219 183 217 185 215 187 213 189 211 210 192 208 194 206 196 204 198 202 200
201 199 203 197 205 195 207 193 209 191 190 212 188 214 186 216 184 218 182 220
180 222 178 224 176 226 174 228 172 230 231 169 233 167 235 165 237 163 239 161
241 159 243 157 245 155 247 153 249 151 150 252 148 254 146 256 144 258 142 260
140 262 138 264 136 266 134 268 132 270 271 129 273 127 275 125 277 123 279 121
281 119 283 117 285 115 287 113 289 111 110 292 108 294 106 296 104 298 102 300
100 302 98 304 96 306 94 308 92 310 311 89 313 87 315 85 317 83 319 81
321 79 323 77 325 75 327 73 329 71 70 332 68 334 66 336 64 338 62 340
60 342 58 344 56 346 54 348 52 350 351 49 353 47 355 45 357 43 359 41
361 39 363 37 365 35 367 33 369 31 30 372 28 374 26 376 24 378 22 380
20 382 18 384 16 386 14 388 12 390 391 9 393 7 395 5 397 3 399 1

五十阶幻方

50
2202 2229 2256 2283 2310 2337 2364 2391 2418 2445 2472 2499 1 28 55 82 109 136 163 190 217 244 271 298 325 1577 1604 1006 1033 1060 1087 1114 1141 1168 1195 1222 1249 626 1278 1305 1332 1359 1386 1413 1440 1467 1494 1521 1548 1575
2228 2255 2282 2309 2336 2363 2390 2417 2444 2471 2498 1900 27 54 81 108 135 162 189 216 243 270 297 324 326 1603 1630 1032 1059 1086 1113 1140 1167 1194 1221 1248 650 652 1304 1331 1358 1385 1412 1439 1466 1493 1520 1547 1574 1576
2254 2281 2308 2335 2362 2389 2416 2443 2470 2497 1899 1901 53 80 107 134 161 188 215 242 269 296 323 350 352 1629 1656 1058 1085 1112 1139 1166 1193 1220 1247 649 651 678 1330 1357 1384 1411 1438 1465 1492 1519 1546 1573 1600 1602
2280 2307 2334 2361 2388 2415 2442 2469 2496 1898 1925 1927 79 106 133 160 187 214 241 268 295 322 349 351 378 1655 1682 1084 1111 1138 1165 1192 1219 1246 648 675 677 704 1356 1383 1410 1437 1464 1491 1518 1545 1572 1599 1601 1628
2306 2333 2360 2387 2414 2441 2468 2495 1897 1924 1926 1953 105 132 159 186 213 240 267 294 321 348 375 377 404 1681 1708 1110 1137 1164 1191 1218 1245 647 674 676 703 730 1382 1409 1436 1463 1490 1517 1544 1571 1598 1625 1627 1654
2332 2359 2386 2413 2440 2467 2494 1896 1923 1950 1952 1979 131 158 185 212 239 266 293 320 347 374 376 403 430 1707 1734 1136 1163 1190 1217 1244 646 673 700 702 729 756 1408 1435 1462 1489 1516 1543 1570 1597 1624 1626 1653 1680
2358 2385 2412 2439 2466 2493 1895 1922 1949 1951 1978 2005 157 184 211 238 265 292 319 346 373 400 402 429 456 1733 1760 1162 1189 1216 1243 645 672 699 701 728 755 782 1434 1461 1488 1515 1542 1569 1596 1623 1650 1652 1679 1706
2384 2411 2438 2465 2492 1894 1921 1948 1975 1977 2004 2031 183 210 237 264 291 318 345 372 399 401 428 455 482 1759 1786 1188 1215 1242 644 671 698 725 727 754 781 808 1460 1487 1514 1541 1568 1595 1622 1649 1651 1678 1705 1732
2410 2437 2464 2491 1893 1920 1947 1974 1976 2003 2030 2057 209 236 263 290 317 344 371 398 425 427 454 481 508 1785 1812 1214 1241 643 670 697 724 726 753 780 807 834 1486 1513 1540 1567 1594 1621 1648 1675 1677 1704 1731 1758
2436 2463 2490 1892 1919 1946 1973 2000 2002 2029 2056 2083 235 262 289 316 343 370 397 424 426 453 480 507 534 1811 1838 1240 642 669 696 723 750 752 779 806 833 860 1512 1539 1566 1593 1620 1647 1674 1676 1703 1730 1757 1784
2462 2489 1891 1918 1945 1972 1999 2001 2028 2055 2082 2109 261 288 315 342 369 396 423 450 452 479 506 533 560 1837 1864 641 668 695 722 749 751 778 805 832 859 886 1538 1565 1592 1619 1646 1673 1700 1702 1729 1756 1783 1810
2488 1890 1917 1944 1971 1998 2025 2027 2054 2081 2108 2135 287 314 341 368 395 422 449 451 478 505 532 559 586 1863 1265 667 694 721 748 775 777 804 831 858 885 912 1564 1591 1618 1645 1672 1699 1701 1728 1755 1782 1809 1836
14 41 68 95 122 149 151 178 205 232 259 286 2188 2215 2242 2269 2296 2323 2350 2352 2379 2406 2433 2460 612 1264 1291 693 720 747 774 776 803 830 857 884 911 938 1590 1617 1644 1671 1698 1725 1727 1754 1781 1808 1835 1862
1915 1942 1969 1996 2023 2050 2052 2079 2106 2133 2160 2187 339 366 393 420 447 474 476 503 530 557 584 611 13 1290 1317 719 746 773 800 802 829 856 883 910 937 964 1616 1643 1670 1697 1724 1726 1753 1780 1807 1834 1861 1263
1941 1968 1995 2022 2049 2051 2078 2105 2132 2159 2186 2213 365 392 419 446 473 500 502 529 556 583 610 12 39 1316 1343 745 772 799 801 828 855 882 909 936 963 990 1642 1669 1696 1723 1750 1752 1779 1806 1833 1860 1262 1289
1967 1994 2021 2048 2075 2077 2104 2131 2158 2185 2212 2239 391 418 445 472 499 501 528 555 582 609 11 38 65 1342 1369 771 798 825 827 854 881 908 935 962 989 1016 1668 1695 1722 1749 1751 1778 1805 1832 1859 1261 1288 1315
1993 2020 2047 2074 2076 2103 2130 2157 2184 2211 2238 2265 417 444 471 498 525 527 554 581 608 10 37 64 91 1368 1395 797 824 826 853 880 907 934 961 988 1015 1042 1694 1721 1748 1775 1777 1804 1831 1858 1260 1287 1314 1341
2019 2046 2073 2100 2102 2129 2156 2183 2210 2237 2264 2291 443 470 497 524 526 553 580 607 9 36 63 90 117 1394 1421 823 850 852 879 906 933 960 987 1014 1041 1068 1720 1747 1774 1776 1803 1830 1857 1259 1286 1313 1340 1367
2045 2072 2099 2101 2128 2155 2182 2209 2236 2263 2290 2317 469 496 523 550 552 579 606 8 35 62 89 116 143 1420 1447 849 851 878 905 932 959 986 1013 1040 1067 1094 1746 1773 1800 1802 1829 1856 1258 1285 1312 1339 1366 1393
2071 2098 2125 2127 2154 2181 2208 2235 2262 2289 2316 2343 495 522 549 551 578 605 7 34 61 88 115 142 169 1446 1473 875 877 904 931 958 985 1012 1039 1066 1093 1120 1772 1799 1801 1828 1855 1257 1284 1311 1338 1365 1392 1419
2097 2124 2126 2153 2180 2207 2234 2261 2288 2315 2342 2369 521 548 575 577 604 6 33 60 87 114 141 168 195 1472 1499 876 903 930 957 984 1011 1038 1065 1092 1119 1146 1798 1825 1827 1854 1256 1283 1310 1337 1364 1391 1418 1445
2123 2150 2152 2179 2206 2233 2260 2287 2314 2341 2368 2395 547 574 576 603 5 32 59 86 113 140 167 194 221 1498 1525 902 929 956 983 1010 1037 1064 1091 1118 1145 1172 1824 1826 1853 1255 1282 1309 1336 1363 1390 1417 1444 1471
2149 2151 2178 2205 2232 2259 2286 2313 2340 2367 2394 2421 573 600 602 4 31 58 85 112 139 166 193 220 247 1524 1526 928 955 982 1009 1036 1063 1090 1117 1144 1171 1198 1850 1852 1254 1281 1308 1335 1362 1389 1416 1443 1470 1497
2175 2177 2204 2231 2258 2285 2312 2339 2366 2393 2420 2447 599 601 3 30 57 84 111 138 165 192 219 246 273 1550 1552 954 981 1008 1035 1062 1089 1116 1143 1170 1197 1224 1851 1253 1280 1307 1334 1361 1388 1415 1442 1469 1496 1523
2176 2203 2230 2257 2284 2311 2338 2365 2392 2419 2446 2473 625 2 29 56 83 110 137 164 191 218 245 272 299 1551 1578 980 1007 1034 1061 1088 1115 1142 1169 1196 1223 1250 1252 1279 1306 1333 1360 1387 1414 1441 1468 1495 1522 1549
327 354 381 408 435 462 489 516 543 570 597 624 1876 1903 1930 1957 1984 2011 2038 2065 2092 2119 2146 2173 2200 952 979 1631 1658 1685 1712 1739 1766 1793 1820 1847 1874 1251 653 680 707 734 761 788 815 842 869 896 923 950
353 380 407 434 461 488 515 542 569 596 623 25 1902 1929 1956 1983 2010 2037 2064 2091 2118 2145 2172 2199 2201 978 1005 1657 1684 1711 1738 1765 1792 1819 1846 1873 1275 1277 679 706 733 760 787 814 841 868 895 922 949 951
379 406 433 460 487 514 541 568 595 622 24 26 1928 1955 1982 2009 2036 2063 2090 2117 2144 2171 2198 2225 2227 1004 1031 1683 1710 1737 1764 1791 1818 1845 1872 1274 1276 1303 705 732 759 786 813 840 867 894 921 948 975 977
405 432 459 486 513 540 567 594 621 23 50 52 1954 1981 2008 2035 2062 2089 2116 2143 2170 2197 2224 2226 2253 1030 1057 1709 1736 1763 1790 1817 1844 1871 1273 1300 1302 1329 731 758 785 812 839 866 893 920 947 974 976 1003
431 458 485 512 539 566 593 620 22 49 51 78 1980 2007 2034 2061 2088 2115 2142 2169 2196 2223 2250 2252 2279 1056 1083 1735 1762 1789 1816 1843 1870 1272 1299 1301 1328 1355 757 784 811 838 865 892 919 946 973 1000 1002 1029
457 484 511 538 565 592 619 21 48 75 77 104 2006 2033 2060 2087 2114 2141 2168 2195 2222 2249 2251 2278 2305 1082 1109 1761 1788 1815 1842 1869 1271 1298 1325 1327 1354 1381 783 810 837 864 891 918 945 972 999 1001 1028 1055
483 510 537 564 591 618 20 47 74 76 103 130 2032 2059 2086 2113 2140 2167 2194 2221 2248 2275 2277 2304 2331 1108 1135 1787 1814 1841 1868 1270 1297 1324 1326 1353 1380 1407 809 836 863 890 917 944 971 998 1025 1027 1054 1081
509 536 563 590 617 19 46 73 100 102 129 156 2058 2085 2112 2139 2166 2193 2220 2247 2274 2276 2303 2330 2357 1134 1161 1813 1840 1867 1269 1296 1323 1350 1352 1379 1406 1433 835 862 889 916 943 970 997 1024 1026 1053 1080 1107
535 562 589 616 18 45 72 99 101 128 155 182 2084 2111 2138 2165 2192 2219 2246 2273 2300 2302 2329 2356 2383 1160 1187 1839 1866 1268 1295 1322 1349 1351 1378 1405 1432 1459 861 888 915 942 969 996 1023 1050 1052 1079 1106 1133
561 588 615 17 44 71 98 125 127 154 181 208 2110 2137 2164 2191 2218 2245 2272 2299 2301 2328 2355 2382 2409 1186 1213 1865 1267 1294 1321 1348 1375 1377 1404 1431 1458 1485 887 914 941 968 995 1022 1049 1051 1078 1105 1132 1159
587 614 16 43 70 97 124 126 153 180 207 234 2136 2163 2190 2217 2244 2271 2298 2325 2327 2354 2381 2408 2435 1212 1239 1266 1293 1320 1347 1374 1376 1403 1430 1457 1484 1511 913 940 967 994 1021 1048 1075 1077 1104 1131 1158 1185
613 15 42 69 96 123 150 152 179 206 233 260 2162 2189 2216 2243 2270 2297 2324 2326 2353 2380 2407 2434 2461 1238 640 1292 1319 1346 1373 1400 1402 1429 1456 1483 1510 1537 939 966 993 1020 1047 1074 1076 1103 1130 1157 1184 1211
1889 1916 1943 1970 1997 2024 2026 2053 2080 2107 2134 2161 313 340 367 394 421 448 475 477 504 531 558 585 2487 639 666 1318 1345 1372 1399 1401 1428 1455 1482 1509 1536 1563 965 992 1019 1046 1073 1100 1102 1129 1156 1183 1210 1237
40 67 94 121 148 175 177 204 231 258 285 312 2214 2241 2268 2295 2322 2349 2351 2378 2405 2432 2459 2486 1888 665 692 1344 1371 1398 1425 1427 1454 1481 1508 1535 1562 1589 991 1018 1045 1072 1099 1101 1128 1155 1182 1209 1236 638
66 93 120 147 174 176 203 230 257 284 311 338 2240 2267 2294 2321 2348 2375 2377 2404 2431 2458 2485 1887 1914 691 718 1370 1397 1424 1426 1453 1480 1507 1534 1561 1588 1615 1017 1044 1071 1098 1125 1127 1154 1181 1208 1235 637 664
92 119 146 173 200 202 229 256 283 310 337 364 2266 2293 2320 2347 2374 2376 2403 2430 2457 2484 1886 1913 1940 717 744 1396 1423 1450 1452 1479 1506 1533 1560 1587 1614 1641 1043 1070 1097 1124 1126 1153 1180 1207 1234 636 663 690
118 145 172 199 201 228 255 282 309 336 363 390 2292 2319 2346 2373 2400 2402 2429 2456 2483 1885 1912 1939 1966 743 770 1422 1449 1451 1478 1505 1532 1559 1586 1613 1640 1667 1069 1096 1123 1150 1152 1179 1206 1233 635 662 689 716
144 171 198 225 227 254 281 308 335 362 389 416 2318 2345 2372 2399 2401 2428 2455 2482 1884 1911 1938 1965 1992 769 796 1448 1475 1477 1504 1531 1558 1585 1612 1639 1666 1693 1095 1122 1149 1151 1178 1205 1232 634 661 688 715 742
170 197 224 226 253 280 307 334 361 388 415 442 2344 2371 2398 2425 2427 2454 2481 1883 1910 1937 1964 1991 2018 795 822 1474 1476 1503 1530 1557 1584 1611 1638 1665 1692 1719 1121 1148 1175 1177 1204 1231 633 660 687 714 741 768
196 223 250 252 279 306 333 360 387 414 441 468 2370 2397 2424 2426 2453 2480 1882 1909 1936 1963 1990 2017 2044 821 848 1500 1502 1529 1556 1583 1610 1637 1664 1691 1718 1745 1147 1174 1176 1203 1230 632 659 686 713 740 767 794
222 249 251 278 305 332 359 386 413 440 467 494 2396 2423 2450 2452 2479 1881 1908 1935 1962 1989 2016 2043 2070 847 874 1501 1528 1555 1582 1609 1636 1663 1690 1717 1744 1771 1173 1200 1202 1229 631 658 685 712 739 766 793 820
248 275 277 304 331 358 385 412 439 466 493 520 2422 2449 2451 2478 1880 1907 1934 1961 1988 2015 2042 2069 2096 873 900 1527 1554 1581 1608 1635 1662 1689 1716 1743 1770 1797 1199 1201 1228 630 657 684 711 738 765 792 819 846
274 276 303 330 357 384 411 438 465 492 519 546 2448 2475 2477 1879 1906 1933 1960 1987 2014 2041 2068 2095 2122 899 901 1553 1580 1607 1634 1661 1688 1715 1742 1769 1796 1823 1225 1227 629 656 683 710 737 764 791 818 845 872
300 302 329 356 383 410 437 464 491 518 545 572 2474 2476 1878 1905 1932 1959 1986 2013 2040 2067 2094 2121 2148 925 927 1579 1606 1633 1660 1687 1714 1741 1768 1795 1822 1849 1226 628 655 682 709 736 763 790 817 844 871 898
301 328 355 382 409 436 463 490 517 544 571 598 2500 1877 1904 1931 1958 1985 2012 2039 2066 2093 2120 2147 2174 926 953 1605 1632 1659 1686 1713 1740 1767 1794 1821 1848 1875 627 654 681 708 735 762 789 816 843 870 897 924
 

JavaScript算法源码

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

const lines = [];
let n, matrix, magic_sum;
rl.on("line", (line) => {
  lines.push(line);

  if (lines.length == 1) {
    n = lines[0] - 0;
  }

  if (n && lines.length == n + 1) {
    lines.shift();
    matrix = lines.map((line) => line.split(" ").map(Number));
    getResult();
    lines.length = 0;
  }
});

function getResult() {
  // 计算幻和
  magic_sum = 0;
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < n; j++) magic_sum += matrix[i][j];
  }
  magic_sum /= n;

  // 记录 和不正确的行号
  const rows = [];
  // 记录 和不正确的列号
  const cols = [];

  for (let row = 0; row < n; row++) {
    if (getRowSum(row) != magic_sum) rows.push(row); // 记录行号
  }

  for (let col = 0; col < n; col++) {
    if (getColSum(col) != magic_sum) cols.push(col); // 记录列号
  }

  // 两点处于同一行,不同列
  if (rows.length == 0) {
    for (let i = 0; i < n; i++) rows.push(i); // 则两点的行坐标可能是任意一行
  }

  // 两点处于同一列,不同行
  if (cols.length == 0) {
    for (let i = 0; i < n; i++) cols.push(i); // 则两点的列坐标可能是任意一列
  }

  // 行号 x 列号,就可以组合出坐标
  const positions = [];
  for (let row of rows) {
    for (let col of cols) positions.push([row, col]);
  }

  // 组合两点,尝试交换
  for (let i = 0; i < positions.length; i++) {
    for (let j = i + 1; j < positions.length; j++) {
      if (isValid(positions[i], positions[j])) return;
    }
  }
}

function isValid(pos1, pos2) {
  // 获取可能出错的两个点的坐标
  const [x1, y1] = pos1;
  const [x2, y2] = pos2;

  // 交换可能出错的两个点的值
  let tmp = matrix[x1][y1];
  matrix[x1][y1] = matrix[x2][y2];
  matrix[x2][y2] = tmp;

  // 首先判断两个对角线和是否为幻和
  let ans = getDiagonalSum1() == magic_sum && getDiagonalSum2() == magic_sum;

  // 判断每一行的和是否为幻和
  if (ans) {
    for (let r = 0; r < n; r++) {
      if (getRowSum(r) != magic_sum) {
        ans = false;
        break;
      }
    }
  }

  // 判断每一列的和是否为幻和
  if (ans) {
    for (let c = 0; c < n; c++) {
      if (getColSum(c) != magic_sum) {
        ans = false;
        break;
      }
    }
  }

  // 如果所有行、列、对角线都相等,则返回对应交换位置
  if (ans) {
    if (x1 * n + y1 < x2 * n + y2) {
      console.log(`${x1 + 1} ${y1 + 1} ${matrix[x1][y1]}`);
      console.log(`${x2 + 1} ${y2 + 1} ${matrix[x2][y2]}`);
    } else {
      console.log(`${x2 + 1} ${y2 + 1} ${matrix[x2][y2]}`);
      console.log(`${x1 + 1} ${y1 + 1} ${matrix[x1][y1]}`);
    }
  } else {
    // 否则复原交换位置
    tmp = matrix[x1][y1];
    matrix[x1][y1] = matrix[x2][y2];
    matrix[x2][y2] = tmp;
  }

  return ans;
}

// 求对应行的和
function getRowSum(r) {
  let sum = 0;
  for (let c = 0; c < n; c++) {
    sum += matrix[r][c];
  }
  return sum;
}

// 求对应列的和
function getColSum(c) {
  let sum = 0;
  for (let r = 0; r < n; r++) {
    sum += matrix[r][c];
  }
  return sum;
}

// 求对角线的和(左上,到右下)
function getDiagonalSum1() {
  let sum = 0;
  for (let i = 0; i < n; i++) {
    sum += matrix[i][i];
  }
  return sum;
}

// 求对角线的和(右上,到左下)
function getDiagonalSum2() {
  let sum = 0;
  for (let i = 0; i < n; i++) {
    sum += matrix[i][n - 1 - i];
  }
  return sum;
}

Java算法源码

import java.util.ArrayList;
import java.util.Scanner;

public class Main {
  static int n; // 幻方的阶数
  static int[][] matrix; // 幻方
  static int magic_sum = 0; // 幻和

  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    n = sc.nextInt();

    matrix = new int[n][n];
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        matrix[i][j] = sc.nextInt();
        magic_sum += matrix[i][j];
      }
    }

    magic_sum /= n;

    getResult();
  }

  public static void getResult() {
    // 记录 和不正确的行
    ArrayList<Integer> rows = new ArrayList<>();
    // 记录 和不正确的列
    ArrayList<Integer> cols = new ArrayList<>();

    for (int row = 0; row < n; row++) {
      if (getRowSum(row) != magic_sum) {
        rows.add(row); // 记录行号
      }
    }

    for (int col = 0; col < n; col++) {
      if (getColSum(col) != magic_sum) {
        cols.add(col); // 记录列号
      }
    }

    // 两点处于同一行,不同列
    if (rows.size() == 0) {
      // 则两点的行坐标可能是任意一行
      for (int i = 0; i < n; i++) rows.add(i);
    }

    // 两点处于同一列,不同行
    if (cols.size() == 0) {
      // 则两点的列坐标可能是任意一列
      for (int i = 0; i < n; i++) cols.add(i);
    }

    // 行号 x 列号,就可以组合出坐标
    ArrayList<int[]> positions = new ArrayList<>();
    for (Integer row : rows) {
      for (Integer col : cols) {
        positions.add(new int[] {row, col});
      }
    }

    // 组合两点,尝试交换
    for (int i = 0; i < positions.size(); i++) {
      for (int j = i + 1; j < positions.size(); j++) {
        if (isValid(positions.get(i), positions.get(j))) return;
      }
    }
  }

  // 尝试交换两个点,看是否可以复原幻方
  public static boolean isValid(int[] pos1, int[] pos2) {
    // 获取可能出错的两个点的坐标
    int x1 = pos1[0], y1 = pos1[1];
    int x2 = pos2[0], y2 = pos2[1];

    // 交换可能出错的两个点的值
    int tmp = matrix[x1][y1];
    matrix[x1][y1] = matrix[x2][y2];
    matrix[x2][y2] = tmp;

    boolean ans = magic_sum == getDiagonalSum1() && magic_sum == getDiagonalSum2();

    // 判断每一行的和是否相等
    if (ans)
      for (int r = 0; r < n; r++) {
        if (getRowSum(r) != magic_sum) {
          ans = false;
          break;
        }
      }

    // 判断每一列的和是否相等
    if (ans)
      for (int c = 0; c < n; c++) {
        if (getColSum(c) != magic_sum) {
          ans = false;
          break;
        }
      }

    // 如果所有行、列、对角线都相等,则返回对应交换位置
    if (ans) {
      if (x1 * n + y1 < x2 * n + y2) {
        System.out.println((x1 + 1) + " " + (y1 + 1) + " " + matrix[x1][y1]);
        System.out.println((x2 + 1) + " " + (y2 + 1) + " " + matrix[x2][y2]);
      } else {
        System.out.println((x2 + 1) + " " + (y2 + 1) + " " + matrix[x2][y2]);
        System.out.println((x1 + 1) + " " + (y1 + 1) + " " + matrix[x1][y1]);
      }
    } else {
      // 否则复原交换位置
      tmp = matrix[x1][y1];
      matrix[x1][y1] = matrix[x2][y2];
      matrix[x2][y2] = tmp;
    }

    return ans;
  }

  // 求对应行的和
  public static int getRowSum(int r) {
    int sum = 0;
    for (int c = 0; c < n; c++) sum += matrix[r][c];
    return sum;
  }

  // 求对应列的和
  public static int getColSum(int c) {
    int sum = 0;
    for (int r = 0; r < n; r++) sum += matrix[r][c];
    return sum;
  }

  // 求对角线的和(左上,到右下)
  public static int getDiagonalSum1() {
    int sum = 0;
    for (int i = 0; i < n; i++) {
      sum += matrix[i][i];
    }
    return sum;
  }

  // 求对角线的和(右上,到左下)
  public static int getDiagonalSum2() {
    int sum = 0;
    for (int i = 0; i < n; i++) {
      sum += matrix[i][n - 1 - i];
    }
    return sum;
  }
}

Python算法源码

# 输入获取
n = int(input())
matrix = [list(map(int, input().split())) for _ in range(n)]


# 求对角线的和(右上,到左下)
def getDiagonalSum2():
    total = 0
    for i in range(n):
        total += matrix[i][n - 1 - i]
    return total


# 求对角线的和(左上,到右下)
def getDiagonalSum1():
    total = 0
    for i in range(n):
        total += matrix[i][i]
    return total


# 求对应列的和
def getColSum(c):
    total = 0
    for r in range(n):
        total += matrix[r][c]
    return total


# 求对应行的和
def getRowSum(r):
    return sum(matrix[r])


# 将一维坐标解析为二维坐标
def getPos(pos):
    x = pos // n
    y = pos % n
    return [x, y]


def isValid(pos1, pos2, magic_sum):
    # 获取可能出错的两个点的坐标
    x1, y1 = pos1
    x2, y2 = pos2

    # 交换可能出错的两个点的值
    matrix[x1][y1], matrix[x2][y2] = matrix[x2][y2], matrix[x1][y1]

    # 首先判断两个对角线和是否等于幻和
    ans = magic_sum == getDiagonalSum1() and magic_sum == getDiagonalSum2()

    # 判断每一行的和是否相等
    if ans:
        for r in range(n):
            if getRowSum(r) != magic_sum:
                ans = False
                break

    # 判断每一列的和是否相等
    if ans:
        for c in range(n):
            if getColSum(c) != magic_sum:
                ans = False
                break

    # 如果所有行、列、对角线都相等,则返回对应交换位置
    if ans:
        if pos1 < pos2:
            print(f"{x1 + 1} {y1 + 1} {matrix[x1][y1]}")
            print(f"{x2 + 1} {y2 + 1} {matrix[x2][y2]}")
        else:
            print(f"{x2 + 1} {y2 + 1} {matrix[x2][y2]}")
            print(f"{x1 + 1} {y1 + 1} {matrix[x1][y1]}")
    else:
        # 否则复原交换位置
        matrix[x1][y1], matrix[x2][y2] = matrix[x2][y2], matrix[x1][y1]

    return ans


# 算法入口
def getResult():
    # 计算幻和
    magic_sum = 0
    for i in range(n):
        for j in range(n):
            magic_sum += matrix[i][j]
    magic_sum /= n

    # 记录 和不正确的行
    rows = []
    # 记录 和不正确的列
    cols = []

    for row in range(n):
        if getRowSum(row) != magic_sum:
            rows.append(row)  # 记录行号

    for col in range(n):
        if getColSum(col) != magic_sum:
            cols.append(col)  # 记录列号

    # 两点处于同一行,不同列
    if len(rows) == 0:
        # 则两点的行坐标可能是任意一行
        rows = [i for i in range(n)]

    # 两点处于同一列,不同行
    if len(cols) == 0:
        # 则两点的列坐标可能是任意一列
        cols = [i for i in range(n)]

    # 行号 x 列号,就可以组合出坐标
    positions = []
    for r in rows:
        for c in cols:
            positions.append((r, c))

    # 组合两点,尝试交换
    for i in range(len(positions)):
        for j in range(i + 1, len(positions)):
            if isValid(positions[i], positions[j], magic_sum):
                return


# 算法调用
getResult()

免责声明:

1、IT资源小站为非营利性网站,全站所有资料仅供网友个人学习使用,禁止商用
2、本站所有文档、视频、书籍等资料均由网友分享,本站只负责收集不承担任何技术及版权问题
3、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除下载链接并致以最深的歉意
4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
5、一经注册为本站会员,一律视为同意网站规定,本站管理员及版主有权禁止违规用户
6、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和IT资源小站的同意
7、IT资源小站管理员和版主有权不事先通知发贴者而删除本文

0

评论0

站点公告

没有账号?注册  忘记密码?