网易笔试十字斩击
游戏工程师小明购买了VR设备之后爱上了体感游戏,而最近他把他的业余时间花在了一
款叫十字斩的游戏
里。当你戴上VR眼镜启动游戏后,先选择-首音乐,然后会发现有一一个NN的方阵呈现在
你的眼前,方阵的
每个格子上都有一个数字。然后伴随着音乐节拍,你需要按照时机对方阵进行一-次十字斩
击(同时斩掉- -行
和一列,而且选好了行列后不能斩到选定行列之外的格子)。斩击完了之后,矩阵会收缩
成一个(N
- . (N-1) 的方阵。
特别的,若该次十字斩斩到的格子数字和是本次所有十字可能里最大的,则会获得-一个
Perfect, 如果N次十
字斩都是Perfect,则可以获得FullCombo的成就。但小明的心算能力不行,至今还未能获
得FullCombo的成
就。所幸初始数字方阵与音乐是一-对应的, 所以小明可以通过预先计算十字斩的位置然
后背下来,游玩的
时候根据记忆去进行十字斩位置的选择即可。
小明上了一天班已经不想写代码了,所以他拜托你来写一-个程序为他计算出十字斩的方
|案。
输入描述:
| 每个输入数据包含一一个测试点。
第一行为一个正整数N,方阵的大小。0 < N <= 500
接下来N行,每行有N个数字,第1行第j个数字表示方阵1行j列上的数字是多少,对于每
个数字,保证是非负整
数且范围在[0, 65535]内。
输出描述:
输出N行,每行两个整数n, m,第i行的n, m表示第1次斩击时,斩击第n行和第m列的数
字和是最大的。注意
如果此时有多种方案,输出n最小的(更小的数字更方便小明记忆),如果还有多种方
案,输出m最小的。
而且n、m的坐标是对于当前的(N + 1 - i) 大小方阵而言,并不是对于一开始N*N大
小的方阵而言,更加详
细的说明参见下方样例说明。
示例1输入输出示例仅供调试,后台判题数据-般不包含示例
输入
3
1 0 0
0 10 10
0 10 10
输出
2 2
1 2
1 1
说明
对于第一轮, 我们斩击2行2列、2行3列、3行2列、3行3列的数字和都是最大的为
30 (行列重复的那个格子的数字并不会被计算两次),但因为希望n和m都最小,所以我们的斩击选择为22
斩击之后剩余的上下左右四个矩阵收缩为新的矩阵
1 0
0 10
此时最优的斩击选择就是1 2 (注意是新方阵下的坐标,而非原方阵的第1行3列)
然后剩下一-个1*1的方阵,只有唯一-的斩击选择1 1了
package com.niukeoffer.a990;
import java.util.Scanner;
public class Main {
public static void main(String arg[]){
int i,j;
Scanner sc =new Scanner(System.in);
int N=sc.nextInt();
int[][] arr= new int[N+1][N+1];
for( i=1;i<=N;i++){
for( j=1;j<=N;j++){
arr[i][j]=sc.nextInt();
}
}
int[] row=new int[N+1];
int[] col=new int[N+1];
for( i=1;i<=N;i++){
for( j=1;j<=N;j++){
arr[0][i]+=arr[j][i];
arr[i][0]+=arr[i][j];
}
}
for(int ci=0;ci<N;ci++){
int max=-1,n=1,m=1;
for( i=1;i<=N;i++){
if(row[i]==1){
continue;
}
for( j=1;j<=N;j++){
if(col[j]==1){
continue;
}
if(arr[i][0]+arr[0][j]-arr[i][j]>max){
max=arr[i][0]+arr[0][j]-arr[i][j];
n=i;
m=j;
}
}
}
int n_out=n,m_out=m;
for(i=1;i<n;i++){
if(row[i]==1) {
n_out -= 1;
}
}
for(j=1;j<m;j++){
if(col[j]==1){
m_out-=1;
}
}
System.out.println(n_out+" "+m_out);
row[n]=1;
col[m]=1;
for(i=1;i<=N;i++){
arr[0][i]-=arr[n][i];
arr[i][0]-=arr[i][m];
}
}
}
}