题解:
假设所有的点都没有障碍,则设分子 a = 3*3+(n-2)*2*4+(n-2)*(n-1)/2*5,分母 b = 3*4+(n-2)*4*4+(n-2)*(n-2)*5。
在(x,y)上加入障碍,则总和的分母要减去当前的点即 b -= v(x,y),如果这个点是 x+y >= n-1,则 a-= v(x,y)。
然后在遍历障碍可以走的路,如果下一步还是障碍则不走,否则 b--,同理下一步也满足 x+y >= n-1,则 a--。
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <bitset>
#include <stack>
#include <cmath>
#include <deque>
#include <queue>
#include <list>
#include <set>
#include <map>
#define mem(a, b) memset(a, b, sizeof(a))
#define inf 0x7ffffff
#define pi acos(-1)
using namespace std;
typedef long long ll;
int step[4][2] = {{1,0}, {0,1}, {-1,0}, {0,-1}};
map<pair<int,int>, int> m;
struct Point{
int x, y;
}point[1000000+10];
int main(){
int t, cas = 0;
scanf("%d", &t);
while(t--){
int n, k;
m.clear();
scanf("%d %d", &n, &k);
int a = 3*3+(n-2)*2*4+(n-2)*(n-1)/2*5;
int b = 3*4+(n-2)*4*4+(n-2)*(n-2)*5;
for(int i = 0; i < k; i++){
int x, y;
scanf("%d %d", &x, &y);
m[make_pair(x,y)] = 1;
point[i].x = x;
point[i].y = y;
}
for(int i = 0; i < k; i++){
int x = point[i].x, y = point[i].y;
if((x == 0 || x == n-1) && (y == 0 || y == n-1)){
b -= 3;
if(x + y >= n-1){
a-= 3;
}
}
else if(x == 0 || x == n-1 || y == 0 || y == n-1){
b -= 4;
if(x + y >= n-1){
a-= 4;
}
}
else{
b -= 5;
if(x + y >= n-1){
a-= 5;
}
}
for(int i = 0; i < 4; i++){
int nx = x+step[i][0], ny = y+step[i][1];
if(nx >= 0 && nx <= n-1 && ny >= 0 && ny <= n-1 && m.count(make_pair(nx,ny)) != 1){
b--;
if(nx+ny >= n-1){
a--;
}
}
}
}
int g = __gcd(a, b);
a /= g;
b /= g;
printf("Case #%d: %d/%d\n", ++cas, a, b);
}
}