题意 在n/*n的棋盘上的n个指定区间上各放1个’车’ 使他们相互不攻击 输出一种可能的方法

行和列可以分开看 就变成了n个区间上选n个点的贪心问题 看行列是否都有解就行

基础的贪心问题 对每个点k选择包含它的最优未使用区间 由于在给k找最优区间时1~k-1的最优区间都已经找好了 所有右界最小的区间肯定是最优区间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <bits/stdc++.h>
using namespace std;
const int N = 5005;
int xl[N], yl[N], xr[N], yr[N], x[N], y[N], n;

bool solve(int a[], int l[], int r[])
{
int cur, mr;
//mr为包含k的区间最小右界,cur为放k的最优区间
memset(a, -1, sizeof(int)*n);
for(int k = 1; k <= n; ++k)
{
cur = -1, mr = N;
for(int i = 0; i < n; ++i)
if(a[i] < 0 && l[i] <= k && r[i] < mr)
mr = r[cur = i];
if(cur < 0 || k > mr) return 0;
a[cur] = k;
}
return 1;
}

int main()
{
while(~scanf("%d", &n), n)
{
for(int i = 0; i < n; ++i)
scanf("%d%d%d%d", &xl[i], &yl[i], &xr[i], &yr[i]);

if(solve(x, xl, xr) && solve(y, yl, yr))
for(int i = 0; i < n; ++i)
printf("%d %d\n", x[i], y[i]);
else puts("IMPOSSIBLE");
}
return 0;
}

Fabled Rooks

We would like to place n rooks, 1 ≤ n ≤ 5000, on a n×n board subject to the following restrictions

The input consists of several test cases. The first line of each of them contains one integer number, n, the side of the board. n lines follow giving the rectangles where the rooks can be placed as described above. The i-th line among them givesxli, yli, xri, and yri. The input file is terminated with the integer `0’ on a line by itself.

Your task is to find such a placing of rooks that the above conditions are satisfied and then outputn lines each giving the position of a rook in order in which their rectangles appeared in the input. If there are multiple solutions, any one will do. Output IMPOSSIBLE if there is no such placing of the rooks.

8 1 1 2 2 5 7 8 8 2 2 5 5 2 2 5 5 6 3 8 6 6 3 8 5 6 3 8 8 3 6 7 8 8 1 1 2 2 5 7 8 8 2 2 5 5 2 2 5 5 6 3 8 6 6 3 8 5 6 3 8 8 3 6 7 8 0

1 1 5 8 2 4 4 2 7 3 8 5 6 6 3 7 1 1 5 8 2 4 4 2 7 3 8 5 6 6 3 7

题意 从4个n元集中各挑出一个数 使它们的和为零有多少种方法

直接n^4枚举肯定会超时的 可以把两个集合的元素和放在数组里 然后排序 枚举另外两个集合中两元素和 看数组中是否有其相反数就行了 复杂度为n^2/*logn

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <bits/stdc++.h>
#define l(i) lower_bound(s,s+m,i)
#define u(i) upper_bound(s,s+m,i)
using namespace std;
const int N = 4005;
int a[N], b[N], c[N], d[N], s[N * N];

int main()
{
int cas, m, k, n;
long long ans;
scanf("%d", &cas);
while(cas--)
{
ans = m = 0;
scanf("%d", &n);
for(int i = 0; i < n; ++i)
scanf("%d%d%d%d", &a[i], &b[i], &c[i], &d[i]);
for(int i = 0; i < n; ++i)
for(int j = 0; j < n; ++j)
s[m++] = a[i] + b[j];
sort(s, s + m);
for(int i = 0; i < n; ++i)
for(int j = 0; j < n; ++j)
k = -c[i] - d[j], ans += (u(k) - l(k));

printf("%lld\n", ans);
if(cas) puts("");
}
return 0;
}

The SUM problem can be formulated as follows: given four lists A, B, C, D of integer values, compute how many quadruplet (a, b, c, d ) $ \in$ A x B x C x D are such that a + b + c + d = 0 . In the following, we assume that all lists have the same size n .

The input begins with a single positive integer on a line by itself indicating the number of the cases following, each of them as described below. This line is followed by a blank line, and there is also a blank line between two consecutive inputs.

The first line of the input file contains the size of the lists n (this value can be as large as 4000). We then have n lines containing four integer values (with absolute value as large as 228 ) that belong respectively to A, B, C and D .

For each test case, the output must follow the description below. The outputs of two consecutive cases will be separated by a blank line.

For each input file, your program has to write the number quadruplets whose sum is zero.

1 6 -45 22 42 -16 -41 -27 56 30 -36 53 -37 77 -36 30 -75 -46 26 -38 -10 62 -32 -54 -6 45

5

Sample Explanation: Indeed, the sum of the five following quadruplets is zero: (-45, -27, 42, 30), (26, 30, -10, -46), (-32, 22, 56, -46),(-32, 30, -75, 77), (-32, -54, 56, 30).

题意 给你二叉树的先序序列和中序序列 求它的后序序列

先序序列的第一个一定是根 中序序列根左边的都属于根的左子树 右边的都属于右子树 递归建树就行了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <bits/stdc++.h>
using namespace std;
typedef struct TNode
{
char data;
TNode *lc, *rc;
} node, *BTree;

void build(BTree &t, string pre, string in)
{
t = new node;
t->lc = t->rc = NULL, t->data = pre[0];
int k = in.find(pre[0]);
if(k > 0) build(t->lc, pre.substr(1, k), in.substr(0, k));
if(k < in.size() - 1) build(t->rc, pre.substr(k + 1), in.substr(k + 1));
}

void postTral(BTree &t)
{
if(!t) return;
postTral(t->lc);
postTral(t->rc);
putchar(t->data);
}

int main()
{
string pre, in;
while(cin >> pre >> in)
{
BTree t;
build(t, pre, in);
postTral(t);
puts("");
}
return 0;
}


Little Valentine liked playing with binary trees very much. Her favorite game was constructing randomly looking binary trees with capital letters in the nodes.

This is an example of one of her creations:

D / \ / \ B E / \ \ / \ \ A C G / / F

To record her trees for future generations, she wrote down two strings for each tree: a preorder traversal (root, left subtree, right subtree) and an inorder traversal (left subtree, root, right subtree).

For the tree drawn above the preorder traversal is DBACEGF and the inorder traversal is ABCDEFG.

She thought that such a pair of strings would give enough information to reconstruct the tree later (but she never tried it).

Now, years later, looking again at the strings, she realized that reconstructing the trees was indeed possible, but only because she never had used the same letter twice in the same tree.

However, doing the reconstruction by hand, soon turned out to be tedious.

So now she asks you to write a program that does the job for her!

The input file will contain one or more test cases. Each test case consists of one line containing two strings preord and inord, representing the preorder traversal and inorder traversal of a binary tree. Both strings consist of unique capital letters. (Thus they are not longer than 26 characters.)

Input is terminated by end of file.

For each test case, recover Valentine’s binary tree and print one line containing the tree’s postorder traversal (left subtree, right subtree, root).

DBACEGF ABCDEFG BCAD CBAD

ACBFGED CDAB

题意 求国际象棋中骑士从一个位置移东到另一个位置所需最少步数

基础的BFS应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <bits/stdc++.h>
using namespace std;
int x[] = { -2, -1, -2, -1, 1, 2, 1, 2};
int y[] = { -1, -2, 1, 2, -2, -1, 2, 1};
int d[15][15], sx, sy, ex, ey;
pair<int, int> q[105], t;

int bfs()
{
int cx, cy, r, c, front = 0, rear = 0;
memset(d, -1, sizeof(d));
d[sx][sy] = 0;
q[rear++] = make_pair(sx, sy);
while(front < rear)
{
t = q[front++];
cx = t.first, cy = t.second;
if(cx == ex && cy == ey) return d[cx][cy];
for(int i = 0; i < 8; ++i)
{
r = cx + x[i], c = cy + y[i];
if(r < 0 || r > 7 || c < 0 || c > 7 || d[r][c] >= 0) continue;
d[r][c] = d[cx][cy] + 1;
q[rear++] = make_pair(r, c);
}
}
}

int main()
{
char a[5], b[5];
while(~scanf("%s%s", a, b))
{
sx = a[0] - 'a', sy = a[1] - '1';
ex = b[0] - 'a', ey = b[1] - '1';
printf("To get from %s to %s takes %d knight moves.\n", a, b, bfs());
}
return 0;
}


A friend of you is doing research on the Traveling Knight Problem (TKP) where you are to find the shortest closed tour of knight moves that visits each square of a given set of n squares on a chessboard exactly once. He thinks that the most difficult part of the problem is determining the smallest number of knight moves between two given squares and that, once you have accomplished this, finding the tour would be easy.

Of course you know that it is vice versa. So you offer him to write a program that solves the “difficult” part.

Your job is to write a program that takes two squares a and b as input and then determines the number of knight moves on a shortest route from a to b.

Input Specification

The input file will contain one or more test cases. Each test case consists of one line containing two squares separated by one space. A square is a string consisting of a letter (a-h) representing the column and a digit (1-8) representing the row on the chessboard.

Output Specification

For each test case, print one line saying “To get from xx to yy takes n knight moves.”.

Sample Input

e2 e4 a1 b2 b2 c3 a1 h8 a1 h7 h8 a1 b1 c3 f6 f6

Sample Output

To get from e2 to e4 takes 2 knight moves. To get from a1 to b2 takes 4 knight moves. To get from b2 to c3 takes 2 knight moves. To get from a1 to h8 takes 6 knight moves. To get from a1 to h7 takes 5 knight moves. To get from h8 to a1 takes 6 knight moves. To get from b1 to c3 takes 1 knight moves. To get from f6 to f6 takes 0 knight moves.

题意 判断输入的括号序列是否是配对的

栈的基础应用 栈顶元素与输入的字符匹配就出栈咯 注意括号序列可以为空

STL栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <bits/stdc++.h>
using namespace std;
int main()
{
int cas;
char c;
cin >> cas;
getchar();
while(cas--)
{
stack<char> s;
while((c = getchar()) != '\n')
{
if(s.empty()) s.push(c);
else if((c == ')' && s.top() == '(')
|| (c == ']' && s.top() == '['))
s.pop();
else s.push(c);
}
puts(s.empty() ? "Yes" : "No");
}
return 0;
}

数组模拟栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<cstdio>
using namespace std;
int main()
{
int cas, top;
char s[200], c;
scanf("%d", &cas);
getchar();
while(cas--)
{
top = 0;
while((c = getchar()) != '\n')
{
if(top == 0) s[top++] = c;
else if(s[top - 1] == '(' && c == ')'
|| s[top - 1] == '[' && c == ']')
--top;
else s[top++] = c;
}
puts(top ? "No" : "Yes");
}
return 0;
}


You are given a string consisting of parentheses () and []. A string of this type is said to becorrect:
(a) if it is the empty string (b) if A and B are correct, AB is correct, (c) if A is correct, (A ) and [A ] is correct.

Write a program that takes a sequence of strings of this type and check their correctness. Your program can assume that the maximum string length is 128.

The file contains a positive integer n and a sequence of n strings of parentheses () and [] , one string a line.

A sequence of Yes or No on the output file.

3 ([]) (([()]))) ([()])()

Yes No Yes

题意 输出n个数m组小于关系的一种可能的拓扑排序

应用dfs拓扑排序 访问j时 若存在i<j且i没被访问 就访问i

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <bits/stdc++.h>
using namespace std;
const int N = 105;
int n, m, t, v[N], tpo[N], g[N][N];

void dfs(int j)
{
if(v[j]) return;
for(int i = 1; i <= n; ++i)
if(g[i][j]) dfs(i);
v[j] = 1;
tpo[++t] = j;
}

int main()
{
int a, b, i;
while(~scanf("%d %d", &n, &m), n)
{
memset(g, 0, sizeof(g));
memset(v, 0, sizeof(v));
while(m--)
{
scanf("%d%d", &a, &b);
g[a][b] = 1;
}

t = 0;
for(i = 1; i <= n; ++i)
if(!v[i]) dfs(i);
for(i = 1; i < n; ++i)
printf("%d ", tpo[i]);
printf("%d\n", tpo[n]);
}
return 0;
}

John has n tasks to do. Unfortunately, the tasks are not independent and the execution of one task is only possible if other tasks have already been executed.

Input

The input will consist of several instances of the problem. Each instance begins with a line containing two integers, 1 <= n <= 100 andm. n is the number of tasks (numbered from 1 to n) and m is the number of direct precedence relations between tasks. After this, there will be m lines with two integers i and j, representing the fact that task i must be executed before task j. An instance with n = m = 0will finish the input.

Output

5 4 1 2 2 3 1 3 1 5 0 0

1 4 2 5 3

题意 模拟程序并行运行

STL队列 双端队列 的应用 用双端队列维护即将执行的程序 再用个队列维护等待变量释放的程序 用lock表示变量锁定状态
先将所有程序依次放到执行队列中 每次取出队首程序运行不超过lim时间 未运行完又放到执行队列队尾
遇到lock时 若当前锁定状态为false就将锁定状态变为true 否则将当前程序放到等待队列队尾并结束运行
遇到unlock时 若等待队列有程序 就将等待队列队首程序放到执行队列队首

遇到end时 退出当前执行(不再进队尾)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <bits/stdc++.h>
using namespace std;
const int N = 1005;
bool lock;
deque<int> qr;//执行队列
queue<int> qb;//等待队列
vector<string> prg[N];
string s;
int t[N], p[N], var[26], lim;

void run(int i)
{
int rt = lim, v;
string cur;
while(rt > 0)
{
cur = prg[i][p[i]];
if(cur[2] == '=') // 赋值
{
rt -= t[0];
v = cur[4] - '0';
if(cur.size() == 6) v = v * 10 + cur[5] - '0';
var[cur[0] - 'a'] = v;
}
else if(cur[2] == 'i') //print
{
rt -= t[1];
printf("%d: %d\n", i, var[cur[6] - 'a']);
}
else if(cur[2] == 'c') //lock
{
rt -= t[2];
if(lock)
{
qb.push(i);
return;
}
else lock = true;
}
else if(cur[2] == 'l') //unlock
{
lock = false;
rt -= t[3];
if(!qb.empty())
{
v = qb.front();
qb.pop();
qr.push_front(v);
}
}
else return; //end
++p[i];
}
qr.push_back(i);
}

int main()
{
int cas, n;
scanf("%d", &cas);
while(cas--)
{
scanf("%d", &n);
for(int i = 0; i < 5; ++i)
scanf("%d", &t[i]);
scanf("%d", &lim);

for(int i = 1; i <= n; ++i)
{
prg[i].clear();
while(getline(cin, s))
{
if(s == "") continue;
prg[i].push_back(s);
if(prg[i].back() == "end") break;
}
qr.push_back(i);
}

memset(p, 0, sizeof(p));
memset(var, 0, sizeof(var));
while(!qr.empty())
{
int cur = qr.front();
qr.pop_front();
run(cur);
}
if(cas) puts("");
}
return 0;
}


Programs executed concurrently on a uniprocessor system appear to be executed at the same time, but in reality the single CPU alternates between the programs, executing some number of instructions from each program before switching to the next. You are to simulate the concurrent execution of up to ten programs on such a system and determine the output that they will produce.

The program that is currently being executed is said to be running, while all programs awaiting execution are said to be ready. A program consists of a sequence of no more than 25 statements, one per line, followed by an end statement. The statements available are listed below.

tex2html_wrap66 tex2html_wrap68

Each statement requires an integral number of time units to execute. The running program is permitted to continue executing instructions for a period of time called its quantum. When a program�s time quantum expires, another ready program will be selected to run. Any instruction currently being executed when the time quantum expires will be allowed to complete.

Programs are queued first-in-first-out for execution in a ready queue. The initial order of the ready queue corresponds to the original order of the programs in the input file. This order can change, however, as a result of the execution of lock and unlock statements.

The lock and unlock statements are used whenever a program wishes to claim mutually exclusive access to the variables it is manipulating. These statements always occur in pairs, bracketing one or more other statements. A lock will always precede an unlock, and these statements will never be nested. Once a program successfully executes a lock statement, no other program may successfully execute a lock statement until the locking program runs and executes the corresponding unlockstatement. Should a running program attempt to execute a lock while one is already in effect, this program will be placed at the end of the blocked queue. Programs blocked in this fashion lose any of their current time quantum remaining. When an unlock is executed, any program at the head of the blocked queue is moved to the head of the ready queue. The first statement this program will execute when it runs will be the lock statement that previously failed. Note that it is up to the programs involved to enforce the mutual exclusion protocol through correct usage of lock andunlock statements. (A renegade program with no lock/unlock pair could alter any variables it wished, despite the proper use of lock/unlock by the other programs.)

Input

The input begins with a single positive integer on a line by itself indicating the number of the cases following, each of them as described below. This line is followed by a blank line, and there is also a blank line between two consecutive inputs.

The first line of the input file consists of seven integers separated by spaces. These integers specify (in order): the number of programs which follow, the unit execution times for each of the five statements (in the order given above), and the number of time units comprising the time quantum. The remainder of the input consists of the programs, which are correctly formed from statements according to the rules described above.

All program statements begin in the first column of a line. Blanks appearing in a statement should be ignored. Associated with each program is an identification number based upon its location in the input data (the first program has ID = 1, the second has ID = 2, etc.).

Output

For each test case, the output must follow the description below. The outputs of two consecutive cases will be separated by a blank line.

Your output will contain of the output generated by the print statements as they occur during the simulation. When a print statement is executed, your program should display the program ID, a colon, a space, and the value of the selected variable. Output from separate print statements should appear on separate lines.

A sample input and correct output are shown below.

Sample Input

1 3 1 1 1 1 1 1 a = 4 print a lock b = 9 print b unlock print b end a = 3 print a lock b = 8 print b unlock print b end b = 5 a = 17 print a print b lock b = 21 print b unlock print b end

Sample Output

1: 3 2: 3 3: 17 3: 9 1: 9 1: 9 2: 8 2: 8 3: 21 3: 21

题意 比较两个字典 按字典序输出所有添加 删除 修改的项 如果没有任何更新 输出 No changes

STL map的应用 对比两个字典 注意开始字符串的处理和字典可以为空

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include<bits/stdc++.h>
using namespace std;
map<string, string> d[2];
map<string, string>::iterator it;
const int N = 105;
string s, a, b, t[N];

void print(char c, int n)
{
sort(t, t + n), cout << c << t[0];
for(int i = 1; i < n; ++i) cout << ',' << t[i];
puts("");
}

int main()
{
int cas, n, c1, c2, c3;
cin >> cas;
while(cas--)
{
d[0].clear(), d[1].clear();
for(int i = 0; i < 2; ++i)
{
cin >> s;
int j = 1, l = s.size();
while(l > 2 && j < l)
{
while(s[j] != ':') a += s[j++]; ++j;
while(s[j] != ',' && s[j] != '}') b += s[j++]; ++j;
d[i][a] = b, a = b = "";
//cout << a << " : " << b << endl;
}
}

c1 = c2 = c3 = 0;
for(it = d[1].begin(); it != d[1].end(); ++it)
if(!d[0].count(it->first)) t[c1++] = it->first;
if(c1) print('+', c1);

for(it = d[0].begin(); it != d[0].end(); ++it)
if(!d[1].count(it->first)) t[c2++] = it->first;
if(c2) print('-', c2);

for(it = d[1].begin(); it != d[1].end(); ++it)
if(d[0].count(it->first) && d[0][it->first] != it->second) t[c3++] = it->first;
if(c3) print('*', c3);

if(!(c1 || c2 || c3)) puts("No changes");
puts("");
}
return 0;
}


In this problem, a dictionary is collection of key-value pairs, where keys are lower-case letters, and values are non-negative integers. Given an old dictionary and a new dictionary, find out what were changed.

Each dictionary is formatting as follows:

{key:value,key:value,…,key:value}

Each key is a string of lower-case letters, and each value is a non-negative integer without leading zeros or prefix `+’. (i.e. -4, 03 and +77 are illegal). Each key will appear at most once, but keys can appear in any order.

The first line contains the number of test cases T ( T$ \le$1000 ). Each test case contains two lines. The first line contains the old dictionary, and the second line contains the new dictionary. Each line will contain at most 100 characters and will not contain any whitespace characters. Both dictionaries could be empty.

WARNING: there are no restrictions on the lengths of each key and value in the dictionary. That means keys could be really long and values could be really large.

For each test case, print the changes, formatted as follows:

If the two dictionaries are identical, print `No changes’ (without quotes) instead.

Print a blank line after each test case.

3 {a:3,b:4,c:10,f:6} {a:3,c:5,d:10,ee:4} {x:1,xyz:123456789123456789123456789} {xyz:123456789123456789123456789,x:1} {first:1,second:2,third:3} {third:3,second:2}

+d,ee -b,f /*c No changes -first

题意 模拟打印队列 队列中有优先级大于队首的元素 队首元素就排到队尾 否则队首元素出队 输出开始在p位置的元素是第几个出队的

直接模拟这个过程就行了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <bits/stdc++.h>
using namespace std;
const int N = 205;
int q[N];
int main()
{
int cas, n, p, cnt, front, rear, i;
scanf("%d", &cas);
while(cas--)
{
scanf("%d%d", &n, &p);
for(i = 0; i < n; ++i) scanf("%d", &q[i]);
cnt = front = 0, rear = n;
while(front <= p)
{
for(i = front + 1; i < rear; ++i)
if(q[i] > q[front]) break;
if(i < rear)
{
if(front == p) p = rear;
q[rear++] = q[front];
}
else ++cnt;
++front;
}
printf("%d\n", cnt);
}
return 0;
}

题意 给你不超过1000个点的坐标 判断这些点是否是关于一条竖线对称的

没想到暴力枚举可以过 如果存在对称轴的话那么对称轴的横坐标一定是最左边的点和最右边的点的中点 为了避免中点是小数 可以将横坐标都乘上2 然后在判断所有点是否有对称点就行了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <bits/stdc++.h>
using namespace std;
const int N = 1005;
int x[N], y[N], n, mx;

bool have(int i)
{
for(int j = 0; j < n; ++j)
if(y[i] == y[j] && x[i] + x[j] == 2 * mx) return true;
return false;
}

int main()
{
int cas, lx, rx, a, i;
scanf("%d", &cas);
while(cas--)
{
lx = rx = 0;
scanf("%d", &n);
for(i = 0; i < n; ++i)
{
scanf("%d%d", &a, &y[i]);
x[i] = a * 2;
if(x[i] < x[lx]) lx = i;
if(x[i] > x[rx]) rx = i;
}
mx = (x[lx] + x[rx]) / 2;
for(i = 0; i < n; ++i)
if(!have(i)) break;

if(i >= n) puts("YES");
else puts("NO");
}
return 0;
}

The figure shown on the left is left-right symmetric as it is possible to fold the sheet of paper along a vertical line, drawn as a dashed line, and to cut the figure into two identical halves. The figure on the right is not left-right symmetric as it is impossible to find such a vertical line.

\epsfbox{p3226.eps}

Write a program that determines whether a figure, drawn with dots, is left-right symmetric or not. The dots are all distinct.

The input consists of T test cases. The number of test cases T is given in the first line of the input file. The first line of each test case contains an integer N , where N ( 1$ \le$N$ \le$1, 000) is the number of dots in a figure. Each of the following N lines contains the x-coordinate and y-coordinate of a dot. Both x-coordinates and y-coordinates are integers between -10,000 and 10,000, both inclusive.

Print exactly one line for each test case. The line should contain YES' if the figure is left-right symmetric. and NO’, otherwise.

The following shows sample input and output for three test cases.

3 5 -2 5 0 0 6 5 4 0 2 3 4 2 3 0 4 4 0 0 0 4 5 14 6 10 5 10 6 14

YES NO YES

0%