2017ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学)

Little Boxes

Problem Description
Little boxes on the hillside.
Little boxes made of ticky-tacky.
Little boxes.
Little boxes.
Little boxes all the same.
There are a green boxes, and b pink boxes.
And c blue boxes and d yellow boxes.
And they are all made out of ticky-tacky.
And they all look just the same.
 


Input
The input has several test cases. The first line contains the integer t (1 ≤ t ≤ 10) which is the total number of test cases.
For each test case, a line contains four non-negative integers a, b, c and d where a, b, c, d ≤ 2^62, indicating the numbers of green boxes, pink boxes, blue boxes and yellow boxes.
 


Output
For each test case, output a line with the total number of boxes.
 


Sample Input
4 1 2 3 4 0 0 0 0 1 0 0 0 111 222 333 404
 


Sample Output
10 0 1 1070
 
Java 即可;
import java.math.*;

import java.util.Scanner;


public class Main {
      public static void main(String[] args) {
      Scanner cin=new Scanner(System.in);
      BigInteger a,b,c,d;
      int T;T=cin.nextInt();
      for(int i=0;i<T;i++) {
    a=cin.nextBigInteger();b=cin.nextBigInteger();c=cin.nextBigInteger();d=cin.nextBigInteger();
    BigInteger res=a.add(b).add(c).add(d);
    System.out.println(res);
      }
    }
      
}

Rabbits

 

Problem Description
Here N (N ≥ 3) rabbits are playing by the river. They are playing on a number line, each occupying a different integer. In a single move, one of the outer rabbits jumps into a space between any other two. At no point may two rabbits occupy the same position.
Help them play as long as possible
 


Input
The input has several test cases. The first line of input contains an integer t (1 ≤ t ≤ 500) indicating the number of test cases.
For each case the first line contains the integer N (3 ≤ N ≤ 500) described as above. The second line contains n integers a1 < a2 < a3 < ... < aN which are the initial positions of the rabbits. For each rabbit, its initial position
ai satisfies 1 ≤ ai ≤ 10000.
 


Output
For each case, output the largest number of moves the rabbits can make.
 


Sample Input
5 3 3 4 6 3 2 3 5 3 3 5 9 4 1 2 3 4 4 1 2 4 5
 


Sample Output
1 1 3 0 1
 
前后分别扫一遍即可,取max;
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>

//#include<cctype>
//#pragma GCC optimize("O3")
using namespace std;
#define maxn 1000005
#define inf 0x3f3f3f3f
#define INF 9999999999
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
#define rdult(x) scanf("%lu",&x)
#define rdlf(x) scanf("%lf",&x)
#define rdstr(x) scanf("%s",x)
typedef long long  ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9 + 7;
#define Mod 1000000000
#define sq(x) (x)*(x)
#define eps 1e-3
typedef pair<int, int> pii;
#define pi acos(-1.0)
//const int N = 1005;
#define REP(i,n) for(int i=0;i<(n);i++)

inline ll rd() {
	ll x = 0;
	char c = getchar();
	bool f = false;
	while (!isdigit(c)) {
		if (c == '-') f = true;
		c = getchar();
	}
	while (isdigit(c)) {
		x = (x << 1) + (x << 3) + (c ^ 48);
		c = getchar();
	}
	return f ? -x : x;
}

ll gcd(ll a, ll b) {
	return b == 0 ? a : gcd(b, a%b);
}
ll sqr(ll x) { return x * x; }

/*ll ans;
ll exgcd(ll a, ll b, ll &x, ll &y) {
	if (!b) {
		x = 1; y = 0; return a;
	}
	ans = exgcd(b, a%b, x, y);
	ll t = x; x = y; y = t - a / b * y;
	return ans;
}
*/



ll qpow(ll a, ll b, ll c) {
	ll ans = 1;
	a = a % c;
	while (b) {
		if (b % 2)ans = ans * a%c;
		b /= 2; a = a * a%c;
	}
	return ans;
}
/*
int n, m;
int st, ed;
struct node {
	int u, v, nxt, w;
}edge[maxn<<1];

int head[maxn], cnt;

void addedge(int u, int v, int w) {
	edge[cnt].u = u; edge[cnt].v = v; edge[cnt].w = w;
	edge[cnt].nxt = head[u]; head[u] = cnt++;
}

int rk[maxn];

int bfs() {
	queue<int>q;
	ms(rk);
	rk[st] = 1; q.push(st);
	while (!q.empty()) {
		int tmp = q.front(); q.pop();
		for (int i = head[tmp]; i != -1; i = edge[i].nxt) {
			int to = edge[i].v;
			if (rk[to] || edge[i].w <= 0)continue;
			rk[to] = rk[tmp] + 1; q.push(to);
		}
	}
	return rk[ed];
}
int dfs(int u, int flow) {
	if (u == ed)return flow;
	int add = 0;
	for (int i = head[u]; i != -1 && add < flow; i = edge[i].nxt) {
		int v = edge[i].v;
		if (rk[v] != rk[u] + 1 || !edge[i].w)continue;
		int tmpadd = dfs(v, min(edge[i].w, flow - add));
		if (!tmpadd) { rk[v] = -1; continue; }
		edge[i].w -= tmpadd; edge[i ^ 1].w += tmpadd; add += tmpadd;
	}
	return add;
}
ll ans;
void dinic() {
	while (bfs())ans += dfs(st, inf);
}
*/

int n;
int a[1000];
int main()
{
	//ios::sync_with_stdio(0);
	//memset(head, -1, sizeof(head));
	int T; cin >> T;
	while (T--) {
		rdint(n);
		for (int i = 1; i <= n; i++)rdint(a[i]);
		int ans = 0;
		for (int i = 2; i < n; i++) {
			ans += (a[i + 1] - a[i] - 1);
		}
		int maxx = ans;
		ans = 0;
		for (int i = n - 1; i > 1; i--) {
			ans += (a[i] - a[i - 1] - 1);
		}
		maxx = max(maxx, ans);
		cout << maxx << endl;
	}
    return 0;
}

Heron and His Triangle

Problem Description
A triangle is a Heron’s triangle if it satisfies that the side lengths of it are consecutive integers t&#8722;1, t, t+ 1 and thatits area is an integer. Now, for given n you need to find a Heron’s triangle associated with the smallest t bigger
than or equal to n.
 


Input
The input contains multiple test cases. The first line of a multiple input is an integer T (1 ≤ T ≤ 30000) followedby T lines. Each line contains an integer N (1 ≤ N ≤ 10^30).
 


Output
For each test case, output the smallest t in a line. If the Heron’s triangle required does not exist, output -1.
 


Sample Input
4 1 2 3 4
 


Sample Output
4 4 4 4
 
找规律:先打表出前几项;
可以发现 num[ i ]=num[ i-1 ]*4-num[ i-2 ];
然后大数即可;
import java.lang.reflect.Array;
import java.math.*;

import java.util.Scanner;



public class Main {
      public static void main(String[] args) {
      Scanner cin=new Scanner(System.in);
      BigInteger N;
      int T;T=cin.nextInt();
      BigInteger num[]=new BigInteger[1000];
      num[1]=BigInteger.valueOf(4);num[2]=BigInteger.valueOf(14);
      for(int i=3;i<=500;i++)num[i]=num[i-1].multiply(BigInteger.valueOf(4)).subtract(num[i-2]);
      for(int i=0;i<T;i++) {
       N=cin.nextBigInteger();
       for(int j=1;j<=400;j++) {
    	   if(num[j].compareTo(N)>=0) {
    		   System.out.println(num[j]);break;
    	   }
       }
      }
    }
      
}

Tree

Problem Description
Consider a un-rooted tree T which is not the biological significance of tree or plant, but a tree as an undirected graph in graph theory with n nodes, labelled from 1 to n. If you cannot understand the concept of a tree here, please omit this problem.
Now we decide to colour its nodes with k distinct colours, labelled from 1 to k. Then for each colour i = 1, 2, · · · , k, define Ei as the minimum subset of edges connecting all nodes coloured by i. If there is no node of the tree coloured by a specified colour i, Ei will be empty.
Try to decide a colour scheme to maximize the size of E1 ∩ E2 · · · ∩ Ek, and output its size.
 


Input
The first line of input contains an integer T (1 ≤ T ≤ 1000), indicating the total number of test cases.
For each case, the first line contains two positive integers n which is the size of the tree and k (k ≤ 500) which is the number of colours. Each of the following n - 1 lines contains two integers x and y describing an edge between them. We are sure that the given graph is a tree.
The summation of n in input is smaller than or equal to 200000.
 


Output
For each test case, output the maximum size of E1 ∩ E1 ... ∩ Ek.
 


Sample Input
3 4 2 1 2 2 3 3 4 4 2 1 2 1 3 1 4 6 3 1 2 2 3 3 4 3 5 6 2
 


Sample Output
1 0 1
 
题意:
考虑一个非根树,它不是树或植物的生物学意义,而是一个树作为图论中的无向图,有n个节点,从1到n标记。 如果你在这里无法理解树的概念,请省略这个问题。
现在我们决定用k个不同的颜色为节点着色,标记为1到k。 然后,对于每种颜色i = 1,2,...,k,将Ei定义为连接由i着色的所有节点的边的最小子集。 如果树的节点没有由指定颜色i着色,则Ei将为空。
尝试确定一个配色方案,以最大化E1∩E2···∩Ek的大小,并输出其大小。
 
 
很明显的一点是:我们K种颜色都要使用,否则一个集合为0,则其交集必然为0;
不仅如此,当我们割去一条边时,树分为两个部分,若两部分大小均>=K,那么ans++;
因为我们枚举的是边,那么如果是交集里的边,则两边的numV>=k,那么我们dfs一次求其子树大小即可;
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>

//#include<cctype>
//#pragma GCC optimize("O3")
using namespace std;
#define maxn 100005
#define inf 0x3f3f3f3f
#define INF 9999999999
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
#define rdult(x) scanf("%lu",&x)
#define rdlf(x) scanf("%lf",&x)
#define rdstr(x) scanf("%s",x)
typedef long long  ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9 + 7;
#define Mod 1000000000
#define sq(x) (x)*(x)
#define eps 1e-3
typedef pair<int, int> pii;
#define pi acos(-1.0)
//const int N = 1005;
#define REP(i,n) for(int i=0;i<(n);i++)

inline ll rd() {
	ll x = 0;
	char c = getchar();
	bool f = false;
	while (!isdigit(c)) {
		if (c == '-') f = true;
		c = getchar();
	}
	while (isdigit(c)) {
		x = (x << 1) + (x << 3) + (c ^ 48);
		c = getchar();
	}
	return f ? -x : x;
}

ll gcd(ll a, ll b) {
	return b == 0 ? a : gcd(b, a%b);
}
ll sqr(ll x) { return x * x; }

/*ll ans;
ll exgcd(ll a, ll b, ll &x, ll &y) {
	if (!b) {
		x = 1; y = 0; return a;
	}
	ans = exgcd(b, a%b, x, y);
	ll t = x; x = y; y = t - a / b * y;
	return ans;
}
*/



ll qpow(ll a, ll b, ll c) {
	ll ans = 1;
	a = a % c;
	while (b) {
		if (b % 2)ans = ans * a%c;
		b /= 2; a = a * a%c;
	}
	return ans;
}
/*
int n, m;
int st, ed;
struct node {
	int u, v, nxt, w;
}edge[maxn<<1];

int head[maxn], cnt;

void addedge(int u, int v, int w) {
	edge[cnt].u = u; edge[cnt].v = v; edge[cnt].w = w;
	edge[cnt].nxt = head[u]; head[u] = cnt++;
}

int rk[maxn];

int bfs() {
	queue<int>q;
	ms(rk);
	rk[st] = 1; q.push(st);
	while (!q.empty()) {
		int tmp = q.front(); q.pop();
		for (int i = head[tmp]; i != -1; i = edge[i].nxt) {
			int to = edge[i].v;
			if (rk[to] || edge[i].w <= 0)continue;
			rk[to] = rk[tmp] + 1; q.push(to);
		}
	}
	return rk[ed];
}
int dfs(int u, int flow) {
	if (u == ed)return flow;
	int add = 0;
	for (int i = head[u]; i != -1 && add < flow; i = edge[i].nxt) {
		int v = edge[i].v;
		if (rk[v] != rk[u] + 1 || !edge[i].w)continue;
		int tmpadd = dfs(v, min(edge[i].w, flow - add));
		if (!tmpadd) { rk[v] = -1; continue; }
		edge[i].w -= tmpadd; edge[i ^ 1].w += tmpadd; add += tmpadd;
	}
	return add;
}
ll ans;
void dinic() {
	while (bfs())ans += dfs(st, inf);
}
*/
int n;
vector<int>vc[maxn];
int Siz[maxn];

void dfs(int u, int rt) {
	Siz[u] = 1;
	for (int i = 0; i < vc[u].size(); i++) {
		int v = vc[u][i];
		if (v == rt)continue;
		dfs(v, u); Siz[u] += Siz[v];
	}
}

int main()
{
	//ios::sync_with_stdio(0);
	//memset(head, -1, sizeof(head));
	int T; rdint(T);
	while (T--) {
		int k; rdint(n); rdint(k);
		for (int i = 0; i < maxn; i++)vc[i].clear();
		for (int i = 1; i < n; i++) {
			int u, v; rdint(u); rdint(v);
			vc[u].push_back(v); vc[v].push_back(u);
		}
		dfs(1, 0);
		int ans = 0;
		for (int i = 1; i <= n; i++) {
			if (Siz[i] >= k && (n - Siz[i]) >= k)ans++;
		}
		cout << ans << endl;
	}
    return 0;
}

Infinite Fraction Path

Problem Description
The ant Welly now dedicates himself to urban infrastructure. He came to the kingdom of numbers and solicited an audience with the king. He recounted how he had built a happy path in the kingdom of happiness. The king affirmed Welly’s talent and hoped that this talent can help him find the best infinite fraction path before the anniversary.
The kingdom has N cities numbered from 0 to N - 1 and you are given an array D[0 ... N - 1] of decimal digits (0 ≤ D[i] ≤ 9, D[i] is an integer). The destination of the only one-way road start from the i-th city is the city labelled (i2 + 1)%N.
A path beginning from the i-th city would pass through the cities u1,u2,u3, and so on consecutively. The path constructs a real number A[i], called the relevant fraction such that the integer part of it is equal to zero and its fractional part is an infinite decimal fraction with digits D[i], D[u1], D[u2], and so on.
The best infinite fraction path is the one with the largest relevant fraction
 


Input
The input contains multiple test cases and the first line provides an integer up to 100 indicating to the total numberof test cases.
For each test case, the first line contains the integer N (1 ≤ N ≤ 150000). The second line contains an array ofdigits D, given without spaces.
The summation of N is smaller than 2000000.
 


Output
For each test case, you should output the label of the case first. Then you are to output exactly N characters which are the first N digits of the fractional part of the largest relevant fraction.
 


Sample Input
4 3 149 5 12345 7 3214567 9 261025520
 


Sample Output
Case #1: 999 Case #2: 53123 Case #3: 7166666 Case #4: 615015015

题意:

一个n个元素的字符串,从 i 位置出发的下一个位置为 (i*i-1)%n;

求最大的路径;

我们 bfs处理;

如果当前达到n个节点,那么弹出队列;

如果从不同位置出发到达了相同的位置,那么也continue,因为后续的过程还是一样;

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>

//#include<cctype>
//#pragma GCC optimize("O3")
using namespace std;
#define maxn 1000005
#define inf 0x3f3f3f3f
#define INF 9999999999
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
#define rdult(x) scanf("%lu",&x)
#define rdlf(x) scanf("%lf",&x)
#define rdstr(x) scanf("%s",x)
typedef long long  ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9 + 7;
#define Mod 1000000000
#define sq(x) (x)*(x)
#define eps 1e-3
typedef pair<int, int> pii;
#define pi acos(-1.0)
//const int N = 1005;
#define REP(i,n) for(int i=0;i<(n);i++)

inline ll rd() {
	ll x = 0;
	char c = getchar();
	bool f = false;
	while (!isdigit(c)) {
		if (c == '-') f = true;
		c = getchar();
	}
	while (isdigit(c)) {
		x = (x << 1) + (x << 3) + (c ^ 48);
		c = getchar();
	}
	return f ? -x : x;
}

ll gcd(ll a, ll b) {
	return b == 0 ? a : gcd(b, a%b);
}
ll sqr(ll x) { return x * x; }

/*ll ans;
ll exgcd(ll a, ll b, ll &x, ll &y) {
	if (!b) {
		x = 1; y = 0; return a;
	}
	ans = exgcd(b, a%b, x, y);
	ll t = x; x = y; y = t - a / b * y;
	return ans;
}
*/



ll qpow(ll a, ll b, ll c) {
	ll ans = 1;
	a = a % c;
	while (b) {
		if (b % 2)ans = ans * a%c;
		b /= 2; a = a * a%c;
	}
	return ans;
}
/*
int n, m;
int st, ed;
struct node {
	int u, v, nxt, w;
}edge[maxn<<1];

int head[maxn], cnt;

void addedge(int u, int v, int w) {
	edge[cnt].u = u; edge[cnt].v = v; edge[cnt].w = w;
	edge[cnt].nxt = head[u]; head[u] = cnt++;
}

int rk[maxn];

int bfs() {
	queue<int>q;
	ms(rk);
	rk[st] = 1; q.push(st);
	while (!q.empty()) {
		int tmp = q.front(); q.pop();
		for (int i = head[tmp]; i != -1; i = edge[i].nxt) {
			int to = edge[i].v;
			if (rk[to] || edge[i].w <= 0)continue;
			rk[to] = rk[tmp] + 1; q.push(to);
		}
	}
	return rk[ed];
}
int dfs(int u, int flow) {
	if (u == ed)return flow;
	int add = 0;
	for (int i = head[u]; i != -1 && add < flow; i = edge[i].nxt) {
		int v = edge[i].v;
		if (rk[v] != rk[u] + 1 || !edge[i].w)continue;
		int tmpadd = dfs(v, min(edge[i].w, flow - add));
		if (!tmpadd) { rk[v] = -1; continue; }
		edge[i].w -= tmpadd; edge[i ^ 1].w += tmpadd; add += tmpadd;
	}
	return add;
}
ll ans;
void dinic() {
	while (bfs())ans += dfs(st, inf);
}
*/

struct node {
	ll stp, pos;
	node(){}
	node(ll stp,ll pos):stp(stp),pos(pos){}
}Nd;
queue<node>q;
int vis[maxn];
int ans[maxn], tmp[maxn];
string s;
int n;

void bfs() {
	while (!q.empty()) {
		node tt = q.front(); q.pop();
		if (tt.stp == n)continue;
		// 已经有n个点,继续
		if (tmp[tt.pos] == ans[tt.stp]) {
			if (vis[tt.pos]==tt.stp)continue;
			// 回到相同的地方
			vis[tt.pos] = tt.stp;
			tt.pos = (tt.pos*tt.pos + 1) % n;
			tt.stp++;// 下一个状态
			if (tmp[tt.pos] >= ans[tt.stp]) {
				ans[tt.stp] = tmp[tt.pos]; q.push(tt);
			}
		}
	}
}


int main()
{
	//ios::sync_with_stdio(0);
	//memset(head, -1, sizeof(head));
	int T; rdint(T);
	for (int j = 1; j <= T; j++) {
		while (!q.empty())q.pop();
		rdint(n); cin >> s;
		int maxx = -inf;
		for (int i = 0; i < n; i++) {
			tmp[i] = s[i] - '0';
			maxx = max(maxx, tmp[i]);
		}
		for (int i = 0; i < n; i++) {
			if (tmp[i] == maxx) {
				q.push(node(1, i));
			}
		}
		memset(vis, -1, sizeof(vis)); memset(ans, -1, sizeof(ans));
		ans[1] = maxx;
		bfs();
		cout << "Case #" << j << ": ";
		for (int i = 1; i <= n; i++)cout << ans[i];
		cout << endl;
	}
    return 0;
}

Wandering Robots

 

Problem Description
In an attempt to colonize Mars, some scientists were tasked with cleaning the planet. A cleaning robot, Marsba,was build with a huge restricted area in the Mars as a massive N × N square grid with K (K ≤ 1000) impassable barriers. This area are numbered from (0, 0) to (N - 1, N - 1) sequentially from left to right, row by row, where N ≤ 10000. The starting point of Marsba is situated on the top left corner lattice (0, 0). Marsba had instructions to program him with equal probability of remaining in the same lattice or travelling to an adjacent one. (Two lattices are said to be adjacent if they share a common edge.) This meant an equal probability being split equally between remaining in the lattice and the number of available routes. Specifically, for the lattice Marsba located in which has d adjacent lattices without impassable barriers, the probability for Marsba of remaining in the lattice or travelling to any adjacent lattice is frac{1}{d+1} .
Then, those scientists completely forgot about it.
Many millennia ago, a young man realizes the importance of the cleaning robot, Marsba, at the end of the forgotten.
For further research, he asks you to calculate the probability of Marsba’s location (x, y) satisfying x + y ≥ N - 1.
Let the probability be an irreducible fraction of the form p/q, you should output p and q respectively, with a fraction slash as the separator.
 


Input
The first line of the input contains an integer t (t ≤ 1000) specifying the number of test cases.
For each case, the first line contains two positive integers N and K. Each of the next K lines contains the coordinate of a barrier.
Note that the starting point (0, 0) has no barrier and all test cases guarantee the connectivity of all lattices free of barriers.
 


Output
For each case output its label first, then output the probability as an irreducible fraction.
 


Sample Input
5 3 0 3 1 1 1 3 2 1 1 2 2 3 3 1 1 1 2 2 2 5 4 1 1 1 2 2 3 3 2
 


Sample Output
Case #1: 2/3 Case #2: 5/8 Case #3: 10/19 Case #4: 7/16 Case #5: 43/71
 
题意:
为了殖民火星,一些科学家的任务是清理地球。一个清洁机器人Marsba在火星上建造了一个巨大的限制区域,是一个巨大的N×N方格,K(K≤1000)无法通过障碍。该区域从(0,0)到(N-1,N-1)从左到右依次逐行编号,其中N≤10000。Marsba的起点位于左上角点阵(0 ,0)。马尔巴指示他以相同的概率保留在同一格子或前往相邻格子中。 (如果两个格子共享共同边缘,则称它们是相邻的。)这意味着在格子中剩余的可用路径数量之间平均分配相等的概率。具体而言,对于位于其中具有d个相邻格子而没有不可通过的障碍的格子Marsba,Marsba保留在格子中或行进到任何相邻格子的概率是 frac {1} {d + 1}。
然后,那些科学家完全忘了它。
几千年前,一位年轻人意识到清洁机器人Marsba在被遗忘的最后阶段的重要性。
为了进一步研究,他要求你计算Marsba位置(x,y)满足x +y≥N - 1的概率。
设概率是p / q形式的不可约分数,你应该分别输出p和q,用分数斜杠作为分隔符。
 
 
数学题:
考虑每个位置的贡献,
角落为3,边上为4,其余为5;
如果某位置为障碍,那么相应的四周-1,该位置置0;
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>

//#include<cctype>
//#pragma GCC optimize("O3")
using namespace std;
#define maxn 1000005
#define inf 0x3f3f3f3f
#define INF 9999999999
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
#define rdult(x) scanf("%lu",&x)
#define rdlf(x) scanf("%lf",&x)
#define rdstr(x) scanf("%s",x)
typedef long long  ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9 + 7;
#define Mod 1000000000
#define sq(x) (x)*(x)
#define eps 1e-3
typedef pair<int, int> pii;
#define pi acos(-1.0)
//const int N = 1005;
#define REP(i,n) for(int i=0;i<(n);i++)

inline ll rd() {
	ll x = 0;
	char c = getchar();
	bool f = false;
	while (!isdigit(c)) {
		if (c == '-') f = true;
		c = getchar();
	}
	while (isdigit(c)) {
		x = (x << 1) + (x << 3) + (c ^ 48);
		c = getchar();
	}
	return f ? -x : x;
}

ll gcd(ll a, ll b) {
	return b == 0 ? a : gcd(b, a%b);
}
ll sqr(ll x) { return x * x; }

/*ll ans;
ll exgcd(ll a, ll b, ll &x, ll &y) {
	if (!b) {
		x = 1; y = 0; return a;
	}
	ans = exgcd(b, a%b, x, y);
	ll t = x; x = y; y = t - a / b * y;
	return ans;
}
*/



ll qpow(ll a, ll b, ll c) {
	ll ans = 1;
	a = a % c;
	while (b) {
		if (b % 2)ans = ans * a%c;
		b /= 2; a = a * a%c;
	}
	return ans;
}
/*
int n, m;
int st, ed;
struct node {
	int u, v, nxt, w;
}edge[maxn<<1];

int head[maxn], cnt;

void addedge(int u, int v, int w) {
	edge[cnt].u = u; edge[cnt].v = v; edge[cnt].w = w;
	edge[cnt].nxt = head[u]; head[u] = cnt++;
}

int rk[maxn];

int bfs() {
	queue<int>q;
	ms(rk);
	rk[st] = 1; q.push(st);
	while (!q.empty()) {
		int tmp = q.front(); q.pop();
		for (int i = head[tmp]; i != -1; i = edge[i].nxt) {
			int to = edge[i].v;
			if (rk[to] || edge[i].w <= 0)continue;
			rk[to] = rk[tmp] + 1; q.push(to);
		}
	}
	return rk[ed];
}
int dfs(int u, int flow) {
	if (u == ed)return flow;
	int add = 0;
	for (int i = head[u]; i != -1 && add < flow; i = edge[i].nxt) {
		int v = edge[i].v;
		if (rk[v] != rk[u] + 1 || !edge[i].w)continue;
		int tmpadd = dfs(v, min(edge[i].w, flow - add));
		if (!tmpadd) { rk[v] = -1; continue; }
		edge[i].w -= tmpadd; edge[i ^ 1].w += tmpadd; add += tmpadd;
	}
	return add;
}
ll ans;
void dinic() {
	while (bfs())ans += dfs(st, inf);
}
*/

int dx[] = { 0,-1,1,0 };
int dy[] = { 1,0,0,-1 };

int T;
int  n, k;
map<pii, int>Map;

int Number(int x, int y) {
	if ((x == 0 && y == 0) || (x == n - 1 && y == 0) || (x == n - 1 && y == n - 1) || (x == 0 && y == n - 1))return 3;
	if ((x == 0) || (y == 0) || (x == n - 1) || (y == n - 1))return 4;
	return 5;
}

int suit(int x, int y) {
	return (x + y) >= n - 1;
}

int OK(int x, int y) {
	return x >= 0 && x < n&&y >= 0 && y < n;
}

int main()
{
	//ios::sync_with_stdio(0);
	//memset(head, -1, sizeof(head));
	rdint(T); int tnt = 0;
	while (T--) {
		tnt++; rdint(n); rdint(k);
		ll sum = 4 * 3 + 4 * (n - 2) * 4 + (n - 2)*(n - 2) * 5;
		ll num3 = 3, num4 = (n - 2) * 2;
		ll num5 = (n + 1)*n / 2 - num3 - num4;
		ll curAns = num5 * 5 + num3 * 3 + num4 * 4;
		Map.clear();
		for (int i = 1; i <= k; i++) {
			int x, y; rdint(x); rdint(y);
			Map[make_pair(x, y)] = Number(x, y);
			for (int j = 0; j < 4; j++) {
				int nx = x + dx[j], ny = y + dy[j];
					if (OK(nx, ny)) {
						Map[make_pair(nx, ny)]++;
						Map[make_pair(nx, ny)] = min(Map[make_pair(nx, ny)], Number(nx, ny));
					}
				}
			}
			int cnt = 0;
			map<pii, int>::iterator it;
			for (auto cnt : Map) {
				int tmpx = cnt.first.first, tmpy = cnt.first.second;
				int tmpz = cnt.second;
				if (suit(tmpx, tmpy))curAns -= tmpz;
				sum -= tmpz;
			}
			ll GCD = gcd(sum, curAns);
			sum /= GCD; curAns /= GCD;
			cout << "Case #" << tnt << ": ";
			cout << curAns << "/" << sum << endl;
		}
		return 0;
	}
EPFL - Fighting
原文地址:https://www.cnblogs.com/zxyqzy/p/10042761.html