皇后相斥问题(UVA 11538)
http://blog.sina.com.cn/s/blog_77dc9e080101hwtz.html
解题思路:
1. 计数问题, 有三种相对摆放方式: 水平, 竖直, 对角线. 根据加法原理即可, 并且没有交集.
水平和竖直是一样的, 只要n*m矩形旋转90度. 所以结果是: n*m*(m-1)+n*m*(n-1);
2. 对角线复杂些, 先来确定对角线的长度: 1,2,3,...,n-2,n-1,n,n,n,...,n,n,n-1,n-2,...,2,1;
其中n的个数是m-n+1 (其中假设m>n);
结果: 2*(2*∑i*(i-1) + (m-n+1)*n*(n-1)) 其中累加的范围是(1<=i<=n-1);
化简得: 2*n*(n-1)*(3*m-n-1)/3
3. 综上所述: n*m*(n+m-2)+2*n*(n-1)*(3*m-n-1)/3
4.平方和公式:1 ^ 2 + 2 ^ 2 + ... + n ^ 2 == n * (n + 1) * (2 * n + 1) / 6
import java.io.*; import java.util.*; import java.math.*; public classMain { long n, m; void run() { while (true) { n = cin.nextInt(); m = cin.nextInt(); if (n == 0 && m == 0) break; if (n > m) { long t = n; n = m; m = t; } long ans = n * m * (n + m - 2); // ans += 2 * n * (n - 1) * (3 * m - n - 1) / 3; ans += 2 * (n * (n - 1) * (2 * n - 1) / 3 - n * (n - 1) + (m - n + 1) * (n - 1) * n); System.out.println(ans); } } public static void main(String[] args) { Mainsolved = new Main(); solved.run(); } static InputStreaminputStream = System.in; static InputReadercin = new InputReader(inputStream); // Scanner cin = new Scanner(new BufferedInputStream(System.in)); } classInputReader { private InputStreamstream; private byte[] buf = new byte[1024]; private int curChar; private int numChars; public InputReader(InputStreamstream) { this.stream = stream; } public int read() { if (numChars == -1) return -1; //throw new InputMismatchException(); if (curChar >= numChars) { curChar = 0; try { numChars = stream.read(buf); } catch (IOExceptione) { throw new InputMismatchException(); } if (numChars <= 0) return -1; } return buf[curChar++]; } public int nextInt() { int c = read(); if (c == -1) return -1; while (isSpaceChar(c)) c = read(); int sgn = 1; if (c == '-') { sgn = -1; c = read(); } int res = 0; do { if (c < '0' || c > '9') throw new InputMismatchException(); res *= 10; res += c - '0'; c = read(); } while (!isSpaceChar(c)); return res * sgn; } public Stringnext() { StringBuilderstr = new StringBuilder(); int ch; while (isSpaceChar(ch = read())); if (ch == -1) return null; do { str.appendCodePoint(ch); } while (!isSpaceChar(ch = read())); return str.toString(); } public static boolean isSpaceChar(int c) { return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1; } public char nextCharacter() { int c = read(); while (isSpaceChar(c)) c = read(); return (char) c; } }