Noip simulation exercises 7

Noip simulation exercises 7

  • Out of 300, I have 20 points. 300 points after correction.
  • Difficulty: Easy.
  • Summary: basic skills to be solid, simple question can not drop points.
  • Per capita AK QAQ. Could you write long snack bar details hua!

Fat mechanic

Description

  • We all know that fat is a mechanical engineer, he was fat, but recently encountered a dilemma,

    This thing is so bothered that his weight dropped to 20%!

    A designer from bothering fat to thin machines 3D design drawings, thin is not so

    Strength, that the drawings painted blurred, but this is not actually square machine other workpieces outside air

    Bit fat 800-degree vision is severely tested, so he spends his time not swallow food.

    Fat man finally could not stand, I decided to turn to the latest technology - computers, he bought a Lenovo computer,

    With drawing it to distinguish, but there is no such software on your computer, so fat with 1 kg of meat as a reward,

    I hope you help him design a software.

    Fat Man said: "My drawings are three-dimensional (advanced bar), divided by a grid coordinate system, each piece contains

    Some adjacent portions of the grid, because the evil of thin people are stupid, I have to think in a blur difference

    Given range of two adjacent cells are the same workpiece, you help me find the total number of workpieces of it. "

Input

  • The first line of three integers l, w, h (l, w, h <= 50) represents a three-dimensional drawing of the length and breadth;

    A second row of an integer m (0 <= m <= 255) represents the maximum allowable degree of blur difference;

    Followed by a line L W H nonnegative integer from 0 to 255, from small to large is given in accordance with the spatial coordinates of each thin Videos

    Blur grid (compare the size of the coordinate, according to length, width, high priority).

Output

  • An integer number of workpieces.

Sample Input

2 2 2

0

1 1 1 1 2 2 2 2

Sample output

2

answer:

  • search for.
  • Search Find Unicom three-dimensional block.
#include <iostream>
#include <cstdio>
#include <cmath>
#define N 55
using namespace std;

int x, y, z, avg, ans;
int a[N][N][N]; //第一维是横切(),第二维是竖切,第三维是立切
bool vis[N][N][N];
int dx[7] = {0, 0, 0, 0, 0, -1, 1};
int dy[7] = {0, 0, 0, -1, 1, 0, 0};
int dz[7] = {0, 1, -1, 0, 0, 0, 0};

int read()
{
    int x = 0; char c = getchar();
    while(c < '0' || c > '9') c = getchar();
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
    return x;
}

void dfs(int v1, int v2, int v3)
{
    for(int i = 1; i <= 6; i++)
    {
        int xx = v1 + dx[i], yy = v2 + dy[i], zz = v3 + dz[i];
        if(xx < 1 || xx > x || yy < 1 || yy > y || zz < 1 || zz > z) continue;
        if(vis[xx][yy][zz]) continue;
        if(abs(a[xx][yy][zz] - a[v1][v2][v3]) <= avg)
        {
            vis[xx][yy][zz] = 1;
            dfs(xx, yy, zz);
        }
    }
}

int main()
{
    cin >> x >> y >> z >> avg;
    for(int i = 1; i <= x; i++)
        for(int j = 1; j <= y; j++)
            for(int k = 1; k <= z; k++)
                a[i][j][k] = read();
    for(int i = 1; i <= x; i++)
        for(int j = 1; j <= y; j++)
            for(int k = 1; k <= z; k++)
                if(!vis[i][j][k])
                {
                    ans++;
                    vis[i][j][k] = 1;
                    dfs(i, j, k);
                }
    cout << ans;
    return 0;
}

Chessboard coverage

Description

  • With 1 1 and 1 2 to cover two kinds domino 2 * N by a board consisting of squares, there can be multiple ways

    Case, the figure shows the N = 1 and N = 2 covers two checkerboard scheme, "■" represents a domino 1, "■■" represents 1 *

    Domino 2, it can be seen, the board has two 2 * 1 coating method, and the board 2 * 2 has seven coating method.

Input

  • Chess.in input file only one row is given a positive value of the integer N, 1≤N≤30, 50% of data

    1≤N≤15。

Output

  • Chess.out also only one row of the output file, is given by 2 N chess cover 1112 and two kinds of domino

    The total number of program disks.

Sample Input

2

Sample output

7

answer:

  • dp。
  • Hey I really did not think about this problem positive solution. Mainly because of a problem to see it think of the provincial election nightmare. Looks like the original title so skipped ... ...

  • In fact, this question seriously think that ordinary dp ah! ! !
  • Consider how a newly added operation, following four cases:
    1. A flat front
    2. A front row of the first protruding, the second row is flat
    3. Before a second row of projecting the first line is flat
    4. Two front rows of projecting of a
  • Then a for loop, which calculates dp (i) (1/2/3/4). Transfer good thought:

  • The arrow is the current line. Then consider the first case, to make the arrow becomes flat, can be transferred from the first case, the bristling fill a 2 1 * 1 * 1 or two, then dp (i, 1) + = dp (i - 1, 1) * 2. May be transferred from the second case, in the second line to fill a 1 * 1 level, then dp (i, 1) + = dp (i - 1, 2). May be transferred from the third case, the same reasons, dp (i, 1) + = dp (i - 1, 3). Can be transferred from the fourth case, do not fill Well, because already tied. Summary: dp (i, 1) = dp (i - 1, 1) * 2 + dp (i - 1, 2) + dp (i - 1, 3) + dp (i - 1, 4).
  • Consider the second case, to make a first row of projections to the current column, the second row flat. It can be transferred from the first three cases. Summary: dp (i, 2) = dp (i - 1, 1) + dp (i - 1, 3). Why can not divert from 2 or 4 case, because only one line considerations relationship with this line!
  • Third, the four cases the same reason, do not push. Then the final dp (n, 1) is also desired.
#include <iostream>
#include <cstdio>
#define int unsigned long long
using namespace std;

int n;
int f[35][5];

signed main()
{
    cin >> n;
    f[0][1] = 1;
    for(int i = 1; i <= n; i++)
    {
        f[i][1] = f[i - 1][1] * 2 + f[i - 1][2] + f[i - 1][3] + f[i - 1][4];
        f[i][2] = f[i - 1][1] + f[i - 1][3];
        f[i][3] = f[i - 1][1] + f[i - 1][2];
        f[i][4] = f[i - 1][1];
    }
    cout << f[n][1];
    return 0;
}

Accumulated precipitation

topic:

  • There are pictures, transfer link

answer:

  • Search / disjoint-set.
  • Explosion easy search timeout, but questions how the data range so small. My thinking is calculated directly with disjoint-set optimization. Complexity is O (nm + V), much faster than the search.
  • For this question, we consider each layer much water can hold. Such enumeration from level 0 to the highest level that the sum of the sum is the answer. That answer how to count each layer of it? We know that, assuming that the current number of layers (height) is h, so if a point height <= h and the border with China Unicom, then this is certainly intolerable. So for each height enumerated, find the location of the point where the height, expanding to four weeks. If the height of the point around <= h, and then this point up to the current point. (Nodes and the number of border merger can be regarded as merged with 0 ultimate answer is this level of access to - size [getFat (0)] ..
#include <iostream>
#include <cstdio>
#include <vector>
#define N 105
using namespace std;

struct Node {int x, y;};
vector<Node> a[N * N];
int n, m, tot, h, ans;
int fat[N * N], size[N * N];
int dx[5] = {0, -1, 1, 0, 0},
    dy[5] = {0, 0, 0, -1, 1};
bool vis[N][N];

int read()
{
    int x = 0; char c = getchar();
    while(c < '0' || c > '9') c = getchar();
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
    return x;
}

int getFat(int x)
{
    if(fat[x] == x) return x;
    return fat[x] = getFat(fat[x]);
}

void merge(int x, int y)
{
    int fx = getFat(x), fy = getFat(y);
    if(fx == fy) return;
    if(size[fx] > size[fy]) swap(fx, fy);
    size[fy] += size[fx], fat[fx] = fy;
}

int cal(int x, int y)
{
    if(x < 1 || x > n || y < 1 || y > m) return 0;
    return (x - 1) * m + y;
}

int main()
{
    freopen("water.in", "r", stdin);
    freopen("water.out", "w", stdout);

    cin >> n >> m;
    for(int i = 1; i <= n * m; i++)
        fat[i] = i, size[i] = 1;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
        {
            int val = read();
            h = max(h, val);
            a[val].push_back((Node){i, j});
        }
    /**
        * 这种一层一层看的思路就是我原先的思路,然后我写挂了。(爆搜
        * 但我没想到用并查集。枚举每一层高度,已知只要 <= 当前高度且与边界相连的点肯定
          会流走。所以用遍历到的点个数 - 这种类型的点个数就是当前层的答案。那么“这种
          类型”的点可以用并查集维护。
     */
    for(int i = 0; i <= h; i++) //这里必须要每个高度枚举到,因为这也是“一层水”
    {
        for(int j = 0; j < a[i].size(); j++)
        {
            int x = a[i][j].x, y = a[i][j].y;
            vis[x][y] = 1, tot++;
            for(int k = 1; k <= 4; k++)
            {
                int xx = x + dx[k], yy = y + dy[k];
                if(xx < 1 || xx > n || yy < 1 || yy > m) merge(cal(x, y), cal(xx, yy));
                if(vis[xx][yy]) merge(cal(x, y), cal(xx, yy));
            }
        }
        ans += tot - size[getFat(0)];
    }
    cout << ans;
    return 0;
}

Guess you like

Origin www.cnblogs.com/BigYellowDog/p/11370068.html