XJOI simulation training 22

A. Minesweeper (minesweeper)

Subject description:

You need to write a demining interaction, a map information is acquired, the player in turn read operation and returns the corresponding result.
Demining situation is a rectangular n × m, where some locations and some landmine clearing position, the situation will demining input character in a matrix form. The position of the i-th row j-th column is denoted as ⟨i, j⟩. In particular, let k be the number of mines, ensure 0 <k <n × m.
A beginning player can not know anything except n, m, k demining situation.
You need to maintain the character matrix named player of the map, the initial matrix for all elements _ (underscore).

Players will be q times operation , each time selecting a location \ (⟨x, y⟩ \) , and click on one of the following three ways (if the game is over, you should ignore all the players operating after the end of the game, it is judged that these operation invalid operation, is the effective operation and vice versa):

  1. Left-click: If \ (⟨x, y⟩ \) has been opened or player map this location is P (P represent the flag), nothing is done; otherwise, if \ (⟨x, y⟩ \) to mine , the game fails; otherwise to \ (⟨x, y⟩ \) opening operation.
  2. Right-click: If \ (⟨x, y⟩ \) has been opened, nothing is done; otherwise, if the player map location \ (⟨x, y⟩ \) is ** ** _ (underscore), which changed to P, if the player map location \ (⟨x, y⟩ \) is P, change it to?, if the player map location \ (⟨x, y⟩ \) is?, to read _.
  3. Click button: If \ (⟨x, y⟩ \) has not been opened, or the number of the player P map around the position adjacent to position 8 is not equal to the value of the position in the map the player, nothing is done operation; otherwise, for \ (⟨x, y⟩ \) around the adjacent 8 is not turned on and the player is not the map position of P, if there is at least one location of mines, the game fails; otherwise be open to these locations .

Opening operation : the position (⟨x, y⟩ \) \ opening operation is performed as follows:

  1. The \ (⟨x, y⟩ \) marked as open.
  2. Player map location \ (⟨x, y⟩ \) instead c (0 ≤ c ≤ 8) , indicates that the number of mines adjacent positions around the position 8.
  3. If c = 0, then around its eight adjacent map is not open and the player is not in the P position opening operation.
  4. This operation is performed recursively until all sub operations after the end of this open end of the operation considered.

Game over , game over the following three conditions:

  1. Game over: That is above the rules, trying to be as open mines operating position will cause the game to fail.
  2. Game victory: If a time after the end of the operation, the number of location is not open exactly k, the operation of the game after the victory.
  3. Quit Game: If a player operation ends, but both cases were not there, then regarded as the player out of the game.

After each operation, you need to return a result , specific rules are as follows:

  • If this operation is invalid operation, return INVALID; otherwise
  • After the game, if the operation fails, the return LOSE; otherwise
  • RUNNING :, then returns to returns with brackets contained in the same row, the player has the map the position and value for changes in the format <x, y, val>; change according to the position of the x coordinate of a first key from small to large, y coordinates of the second keyword ascending sort order, change positions with two adjacent, spaced apart. After a certain time, for example, operation may return: RUNNING: []; or RUNNING: [<3, 3,?>]. Note the location where the spaces.
  • If this operation after the victory of the game, then return to WIN on a new line.
  • If after this operation out of the game, then return QUIT on a new line.

Input formats:

Input files contain multiple sets of data.
The first line of a positive integer and T represents the number of data sets, the next lines per + q + 2 n (meaning below) a set of data.
The first line of each set of two positive integers n, m respectively represent the height and width demining situation.
N lines of each data Next, the i-th row of a string of length m, and contains only _ \ (* \) two character.
If the j-th character is *, then the i-th row and j as mines, otherwise open space.
Then each set of a plurality of data lines, each line three positive integers op, x, y represents a player's operation, specific operations, see the title described.
Each a number of 0 in the last row, represents the end of a player operation. Players make the number of operations to q.

Output formats:

For each test, a plurality of output lines, each line represents the results of a return operation, when a single operation after the end of the game , output a corresponding result.
Using a line between two adjacent data \ (============== \) (= 10 characters, without the quotes) apart.

data range :

For all test points: 1 ≤ T ≤ 30,3 ≤ n, m ≤ 200,0 ≤ q ≤ 10000, op ∈ {1, 2, 3}, 1 ≤ x ≤ n, 1 ≤ y ≤ m;

Solution :

Rarely doA good simulation title,
subject in each case is already described very clearly, that Italy strongly simulated by just fine.
Definition of invalid operation not see cause burst = w = zero

Code :

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define fr(i, a, b) for(int (i) = (a); (i) <= (b); (i)++)
typedef pair<int, int> pii;
typedef pair<pii, int> pli;
const int N = 205;
int n, m, T, close;
char s[N][N], a[N][N];
vector<pli> prt;
template <class T> void read(T &x) {
    bool f = false; x = 0;
    char ch = getchar();
    while (ch<'0' || ch>'9') {if (ch == '-') f = true; ch = getchar();}
    while (ch>='0' && ch<='9') x = x * 10 + ch - '0', ch = getchar();
    if (f) x = -x;
}
inline void open(int x, int y) {
    close --;
    int cnt = 0;
    fr(i, x - 1, x + 1) fr(j, y - 1, y + 1) {
        if (i < 1 || i > n || j < 1 || j > m) continue;
        if (a[i][j] == '*') cnt++;
    }
    prt.pb(mp(mp(x, y), cnt));
    s[x][y] = '0' + cnt;
    if (cnt == 0) {
        fr(i, x - 1, x + 1) fr(j, y - 1, y + 1) {
            if (i < 1 || i > n || j < 1 || j > m) continue;
            if (s[i][j] == '_' || s[i][j] == '?') {
                open(i, j);
            }
        }
    }
}
inline void shuchu() {
    sort(prt.begin(), prt.end());
    int sz = prt.size() - 1;
    printf("RUNNING: [");
    fr(i, 0, sz) {
        printf("<%d, %d, %d>", prt[i].fi.fi, prt[i].fi.se, prt[i].se);
        if (i != sz) printf(", ");
    }
    puts("]");
}
int main() {
    read(T);
    while (T--) {
        read(n), read(m);
        int mine = 0;
        fr(i, 1, n) {
            scanf("%s", a[i] + 1);
            fr(j, 1, m) if (a[i][j] == '*') mine++;
        }
        fr(i, 1, n) fr(j, 1, m) s[i][j] = '_';
        int op, x, y; close = n * m;
        bool lose = false, win = false;
        while (~scanf("%d", &op)) {
            if (op == 0) {
                if (!win && !lose) puts("QUIT");
                break;
            }
            read(x), read(y);
            if (lose || win) {puts("INVALID"); continue;}
            if (op == 1) {
                if (s[x][y] >= '0' && s[x][y] <= '9' || s[x][y] == 'P')  {puts("RUNNING: []"); continue;}
                if (a[x][y] == '*') {
                    puts("LOSE"); lose = true;
                    continue;
                }
                prt.clear();
                open(x, y); shuchu();
                if (close == mine) {puts("WIN"); win = true; continue;}
            }
            if (op == 2) {
                if (s[x][y] >= '0' && s[x][y] <= '9')  {puts("RUNNING: []"); continue;}
                if (s[x][y] == '_') s[x][y] = 'P';
                else if (s[x][y] == 'P') s[x][y] = '?';
                     else s[x][y] = '_';
                printf("RUNNING: [<%d, %d, %c>]\n", x, y, s[x][y]);
            }
            if (op == 3) {
                if (!(s[x][y] >= '0' && s[x][y] <= '9')) {puts("RUNNING: []"); continue;}
                int cnt = 0;
                fr(i, x - 1, x + 1) fr(j, y - 1, y + 1) {
                    if (i < 1 || i > n || j < 1 || j > m) continue;
                    if (s[i][j] == 'P') cnt++;
                }
                if (cnt != (s[x][y] - '0')) {puts("RUNNING: []"); continue;}
                prt.clear();
                fr(i, x - 1, x + 1) {
                    fr(j, y - 1, y + 1) {
                        if (i < 1 || i > n || j < 1 || j > m) continue;
                        if (s[i][j] == 'P' || (s[i][j] >= '0' && s[i][j] <= '9')) continue;
                        if (a[i][j] == '*') {
                            lose = true;
                        } else open(i, j);
                    }
                }
                if (lose) {puts("LOSE"); continue;}
                shuchu();
                if (close == mine) {puts("WIN"); win = true; continue;}
            }
        }
        if (T) puts("==========");
    }
    return 0;
}

B. multicolored tree (Colorful)

Subject description:

Given a \ (n-\) nodes of the tree, the node number \ (. 1 ~ n-\) . Each node are infected with a color, a total of \ (m \) different colors, numbered \ (m. 1 ~ \) . Note node \ (I \) of the color \ (C_i \) . Small X like the color, he wants to choose a part of the tree communicating \ (S \) , and \ (S \) in the node must contain at least \ (k \) different colors. That \ (S \) must be satisfied, which is a connected subgraph of the original tree, and set \ ({c_u | u ∈ S } \) a size of at least \ (K \) . Y hate the color but little, she let the little X in addition to (S \) \ outside the nodes in the color of all nodes are erased and stay in a node \ (U \) , she wants to maximize node \ ( U \) has a minimum value of the distance between nodes and an arbitrary color. That is maximized \ (min \ {DIS (U, X) \} ∈ S X \) , \ (DIS (X, Y) \) indicate nodes \ (X \)And the node (Y \) \ distance, where through a minimum number of edges defined by the distance. X has not yet determined a small select \ (S \) program, he turned to you, you need all of the above conditions are met, and maximize \ (u \) and \ (S \) from the node.

Input formats:

The first line of three positive integers \ (n-, m, K \) , meaning the subject see description.
The second row \ (n-\) positive integers \ (c1 ... n \) sequentially show the color of each node.
Next \ (n - 1 \) lines of two positive integers \ (x, y \) represents a connection node \ (X \) and the node \ (Y \) side.

Output formats:

Output a line number represents the maximum distance.

Example:

Entry

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

Export

3

data range :

For all data, \ (. 1 ≤ K ≤ m ≤ n-≤ 10. 6 ^ \) , \ (. 1 ≤ m ≤ CI \) .

Solution :

The tree is a tree without roots, we handpicked No. 1-point-rooted greedy think, the last elected sub-graph \ (S \) There are two cases

  1. 1 is a sub-tree rooted
  2. 1 is a rooted tree by deleting a subtree

In the first case, the minimum value may be dis dp find out
the second case, the maximum depth to direct dfs find
that we can obtain a value for the two cases dis subtree rooted respectively one point of
contact depending on the color count down to a point and the subtree rooted not contain this subtree
consider the subtree rooted at some point dfs sequence is continuous, then the copy dfs later, a point is omitted for the remaining part of the root of the subtree is also continuous, so we can directly process in order dfs dfs sequence in the double pointer k reaches every point position of the first color, determines whether the position included in the point tree inside can be.

dfs order really a good thing = w =

Code :

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 7, inf = 1e9 + 7;
int n, m, k, cnt = 0, inx = 0;
int c[N], ct[N], num[N * 2], in[N], out[N];
int fir[N], nxt[N * 2], to[N * 2], dis[N], Mx[N], pos[N * 2];
inline void AddEdge(int u, int v) {
    nxt[++cnt] = fir[u];
    fir[u] = cnt, to[cnt] = v;
}
void dfs1(int u, int fa) {
    in[u] = ++inx;
    num[inx] = u;
    for (int i = fir[u]; i; i = nxt[i]) {
        int v = to[i];
        if (v == fa) continue;
        dfs1(v, u);
        dis[u] = max(dis[u], dis[v] + 1);
    }
    out[u] = inx;
}
void dfs2(int u, int fa) {
    int mx = 0, cmx = 0;
    for (int i = fir[u]; i; i = nxt[i]) {
        int v = to[i];
        if (v == fa) continue;
        if (dis[v] + 1 >= mx) cmx = mx, mx = dis[v] + 1;
        else cmx = max(cmx, dis[v] + 1);
    }
    for (int i = fir[u]; i; i = nxt[i]) {
        int v = to[i];
        if (v == fa) continue;
        Mx[v] = max(Mx[u] + 1, (dis[v] + 1 == mx) ? cmx + 1 : mx + 1);
        dfs2(v, u);
    }
}
int main() {
    scanf("%d%d%d", &n, &m, &k);
    for (int i = 1; i <= n; i++) scanf("%d", &c[i]);
    for (int i = 1; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        AddEdge(x, y);
        AddEdge(y, x);
    }
    dfs1(1, 0);
    dfs2(1, 0);
    for (int i = 1; i <= n; i++) num[i + n] = num[i];
    int nw = 0;
    for (int i = 1, j = 1; j <= 2 * n; j++) {
        if (ct[c[num[j]]] == 0) nw ++;
        ct[c[num[j]]] ++;
        while (nw > k || ct[c[num[i]]] > 1) {
            ct[c[num[i]]] --;
            if (ct[c[num[i]]] == 0) nw --;
            i ++;
        }
        if (nw >= k) pos[j] = i;
    }
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        if (pos[out[i]] >= in[i]) ans = max(ans, Mx[i]);
        if (pos[in[i] + n - 1] > out[i]) ans = max(ans, dis[i] + 1);
    }
    printf("%d\n", ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/bryane/p/11758100.html