QueenAttack
问题分析:
1.对于行和列,要求得每行或每列的棋子个数,只需要把横坐标或纵坐标相同的棋子数目相加即可,然后使用k*(k-1)/2就可求得攻击次数
2.对于对角线上的点,需要分析对角线上点的坐标关系。分析得到,右下对角线上的点横纵坐标之差相等,左下对角线上的点横纵坐标之和相等,分析出来后接下来做法就和处理行和列上点一样。
import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Scanner; public class QueenAttack{ public static void main(String[] args) { Scanner scan = new Scanner(System.in); while (scan.hasNext()) { int n = scan.nextInt(); HashMap<Integer, Integer> mapRow = new HashMap<Integer, Integer>(); HashMap<Integer, Integer> mapCol = new HashMap<Integer, Integer>(); HashMap<Integer, Integer> mapLeft = new HashMap<Integer, Integer>(); HashMap<Integer, Integer> mapRight = new HashMap<Integer, Integer>(); int[][] array = new int[n][2]; // 输入放有棋子的横纵坐标,同时计算出每行有多少个棋子,每列有多少个棋子 for (int i = 0; i < n; i++) { array[i][0] = scan.nextInt(); int x = array[i][0]; array[i][1] = scan.nextInt(); int y = array[i][1]; // 计算当前行有多少棋子 numChess(mapRow, x); // 计算当前列有多少棋子 numChess(mapCol, y); // 计算左下对角线上棋子数目,满足在同一左下对角线上的条件是横纵坐标之和相等,所以传入参数是横纵坐标之和 numChess(mapLeft, x + y); // 计算右下对角线上棋子数目,满足在同一右下对角线上的条件是横纵坐标之差相等,所以传入参数是横纵坐标之差 numChess(mapRight, y - x); } // 计算每行有多少次攻击 int numRow = numAttack(mapRow); // 计算每列有多少次攻击 int numCol = numAttack(mapCol); // 计算左下对角线上攻击次数 int numLeft = numAttack(mapLeft); // 计算右下对角线上攻击次数 int numRight = numAttack(mapRight); System.out.println(numRow + numCol + numLeft + numRight); } } // 计算每行、每列或对角线上的棋子数目 public static void numChess(HashMap<Integer, Integer> map, int key) { if (map.containsKey(key)) { map.put(key, map.get(key) + 1); } else { map.put(key, 1); } } // 计算每行、每列或对角线上的攻击次数 public static int numAttack(HashMap<Integer, Integer> map) { Iterator iter = map.entrySet().iterator(); int count = 0; while (iter.hasNext()) { Map.Entry<Integer, Integer> entry = (Map.Entry<Integer, Integer>) iter.next(); Integer val = entry.getValue(); if (val >= 2) { count = count + val * (val - 1) / 2; } } return count; } }