Noip simulation training 2

Noip simulation training 2

  • Out of 260. T1 100, T2 50, T3 60
  • I first 70 from a revised 260
  • Easier

T1: Minesweeper

Description

  • A N × M (1≤N, M≤100) mesh region, labeled "#" as the barrier region grid, the grid is marked with number minefield, the digital data is the area of ​​mines. A flail vehicle starting from the upper left corner, and can only go to the right or down, mine clearance vehicle can not enter the hazard, in addition it traveled grid mines will be removed. Your task is to compile a program, finding a departure from the top left corner of the grid (1, 1) to reach the lower right corner of the grid (N, M) and mine-clearing most of the route. Below is a sample grid of 4 × 5, the best route can be cleared 6 demining mines.

    1
    2 3
    3
    1

Input

  • The first line of the input file is mine.in two integers N and M, separated by a space between the two numbers. The next N rows, each row having M integers, wherein a negative number indicates that the region is a barrier region, a non-negative number indicates a minefield, and the integer represents the total number of mines in the area, with the same row between two adjacent integers a separate space.

Output

  • Output file mine.out only one row, if the demining of the route does not exist, that there is no path from the upper left to the lower right corner, then the output "No answer", or output an integer representing the maximum number of mines cleared.

Sample Input

4 5

0 1 0 0 0

2 –1 3 –1 0

0 3 0 –1 –1

-1 –1 0 1 0

Sample output

6

answer:

  • dp. But it took 70. At that time thought of the situation will come to the stage a little, but just take it for granted, not to implement the code, think this should not be a problem. So after dp pay attention to feasibility, updated condition

  • and so:
    1. Note that various conditions: boundary conditions, the update condition, initialization
    2. Do not take it for granted
#include <iostream>
#include <cstdio>
#define maxn 105
using namespace std;

int n, m;
int a[maxn][maxn], f[maxn][maxn];
bool can[maxn][maxn];

int main()
{
    can[0][1] = can[1][0] = 1; //初始化!!
    cin >> n >> m;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
        {
            cin >> a[i][j];
            if(a[i][j] < 0) a[i][j] = -1;
        }
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            if(a[i][j] != -1)
            {
                if(can[i - 1][j] || can[i][j - 1]) can[i][j] = 1;
                if(can[i - 1][j] || can[i][j - 1]) f[i][j] = max(f[i - 1][j], f[i][j - 1]) + a[i][j];
            }
    if(!can[n][m]) cout << "No answer";
    else cout << f[n][m];
    return 0;
}

T2: City Tour

Description

  • L is a modern city tourist city, a straight strip of cross streets, rectangular network of rules, each street is numbered with an integer, as shown, the network represents the intersection of two streets intersection, which :( coordinate representation to the point where the level of street number, street number of the point where the vertical), the provisions of the city center coordinates (0, 0). (Figure no it does not matter)

    The city has the M crossing traffic light system for maintenance and placed roadblocks impassable, a group of tourists walking tour of the city, in order to make the trip more interesting, they developed the following rules: From the city center, every step along the street through a network cells, in addition to the first step can take the four directions, the rest of the step by step based on the previous turn left or right by 90 degrees, the first step requires N just return to the starting point (0, 0), while the intermediate points remaining It can not be repeated .

    In the figure above, starting from (0,0) can not take three steps back to the beginning; and go back to the beginning of the four-step path to only two: one of which is: (0,0) → (-1,0) → (-1,1) → (0,1) → (0,0),

    And the other is: (0,0) → (0,1) → (-1,1) → (-1,0) → (0,0).

    Your job is that for a given number N, M and M-th obstacle distribution, programming find all tour path.

Input

  • The first line of the input file is sight.in two integers N and M, where N represents a tour course of step

    Number, and M represents the number of the obstacle, wherein 0≤N≤40,0≤M≤50. The next M rows, each row coordinates are given by a two integers obstacle, between two adjacent integers separated by a space.

Output

  • Output file sight.out only one row, the number given to meet the requirements of the tour route.

Sample Input

4 2

0 –1

1 0

Sample output

2

answer:

  • Search, need pruning. But the first to write a wrong question ... ... "among the remaining points can not be repeated," these words did not see. But after the first amendment only got one point. Because the idea did not expect to be pruning (pruning should not think of the line), pruning is "a place to go after the judge has enough a few steps back to the beginning," but count the number of steps was hard, push for a long time (see program). But after the completion of a second correction, or only the one point. Then I wonder if map is too slow? Then translated into the coordinates of all the presence of a positive number of array operation, then A out.

  • and so:

    1. There is a negative number can coordinate the whole translation

    2. It can search for pruning pruning

    3. STL need to be cautious

#include <iostream>
#include <cstdio>
#define maxn 2005
#define k 100 //平移系数
using namespace std;

int mp[maxn][maxn], need[maxn][maxn];
bool vis[maxn][maxn];
int t, n, ans;
int dx[5][3] = {
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 1, -1},
{0, -1, 1}
};
int dy[5][3] = {
{0, 0, 0},
{0, -1, 1},
{0, 1, -1},
{0, 0, 0},
{0, 0, 0}
};

inline int cal(int turn, int flag)
{
    if(flag == 1)
        {if(turn == 1) return 3; if(turn == 2) return 4; if(turn == 3) return 2; if(turn == 4) return 1;}
    else
        {if(turn == 1) return 4; if(turn == 2) return 3; if(turn == 3) return 1; if(turn == 4) return 2;}
    return 0;
}

inline int call(int x, int y) {
    x = abs(x - k), y = abs(y - k);
    if((x % 2 == 0 && y % 2 == 0) || (x % 2 != 0 && y % 2 != 0)) return 2 * x;
    else return 2 * (x - 1) + 1;
}

inline void dfs(int x, int y, int step, int turn)
{
    if(mp[x][y] == -1) return;
    if(!need[x][y]) need[x][y] = call(x, y);
    if(step + need[x][y] > t + 1) return;
    if(step > t)
    {
        if(x == k && y == k) {ans++; return;}
        return;
    }
    int xx, yy;
    xx = x + dx[turn][1], yy = y + dy[turn][1];
    if(!vis[xx][yy])
    {
        vis[xx][yy] = 1;
        dfs(xx, yy, step + 1, cal(turn, 1));
        vis[xx][yy] = 0;
    }
    if(xx == k && yy == k && step == t) dfs(xx, yy, step + 1, cal(turn, 1));
    xx = x + dx[turn][2], yy = y + dy[turn][2];
    if(!vis[xx][yy])
    {
        vis[xx][yy] = 1;
        dfs(xx, yy, step + 1, cal(turn, 2));
        vis[xx][yy] = 0;
    }
    if(xx == k && yy == k && step == t) dfs(xx, yy, step + 1, cal(turn, 2));
}

int main()
{
    freopen("sight.in", "r", stdin);
    freopen("sight.out", "w", stdout);
    
    vis[k][k] = 1;
    cin >> t >> n;
    for(int i = 1; i <= n; i++)
    {
        int x, y;   cin >> x >> y;
        mp[x + k][y + k] = -1;
    }
    vis[k][-1 + k] = 1, dfs(k, -1 + k, 2, 3), vis[k][-1 + k] = 0;
    vis[k][1 + k] = 1, dfs(k, 1 + k, 2, 4), vis[k][1 + k] = 0;
    vis[-1 + k][k] = 1, dfs(-1 + k, k, 2, 1), vis[-1 + k][k] = 0;
    vis[1 + k][k] = 1, dfs(1 + k, k, 2, 2), vis[1 + k][k] = 0;
    cout << ans;
    return 0;
}

Prime partner

Description

  • If both positive integers and is a prime number, which we call "prime partner", such as 2 and 5, 6 and 13, which are said encryption can be applied to the communication. Now the password you learn to design a program, pick out several pairs' prime partner ", choose from a variety of schemes have been some positive integer n, for example, there are four positive integers: 2,5,6,13, if 5 and 6 can be divided into a group to give a set of "prime partner", while the 2 and 5,6 and 13 consist obtained two "prime partner", can be composed of "prime partner" up scheme is called " the best solution ", of course, learn the password you want to find out the" best solution. "

Input

  • The first line of the input file prime.in a positive integer n, where n is not more than 400 indicates the number of natural numbers to be selected. The second line gives the n positive integer of not more than 30,000, between two adjacent sub-numbers with a space

    open.

Output

  • Output file prime.out only one row, gives the "best solution" you obtained form the "prime partner" of the number of pairs.

Sample Input

4

2 5 6 13

Sample Output

2

answer:

  • The original idea is as follows:
    • For two and the number of prime numbers, and even a number of both sides
    • Even after completing, a graph is formed
    • This figure is in fact a tree :( proof follows)
    • A + B = a known prime number, B + C = prime number; Q A + C =?
    • Because an odd prime number, the A, B, respectively odd and even
    • When A is an odd number, an odd number of C can be introduced, so that C = A + even number! = Prime number
    • When A is an even number, an even number of C can be introduced, so that C = A + even number! = Prime number
    • In sum, A + C = Number of bonded
    • So in the sense of drawing, there is no ring, so this is a tree diagram
    • Then the figure is behind a tree, I can take the longest chain of this tree, the answer is the longest chain / 2 (rounded down)
  • But, the whole burst.

  • Because when A = 1, B = 1, C = time 1, A + C = prime! This is contradictory to the conclusion push above, so there FIG ring!

    So this idea needs to be improved.

  • Positive Solutions of bipartite graph matching: If the data is not 1, then, my algorithm is feasible. Positive Solutions of Hungary algorithm can be used, all of the odd-numbered side of that, all even on the other side, to find a partner with an odd, odd when one partner can not be found, if it is, then 1, then accumulated into a single variable. The total number of successful pairing, plus the total number of unpaired 1 divided by 2, is the answer.

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#define maxn 405
using namespace std;

int n, cnt1, cnt2, ans, tot;
int a[maxn], b[maxn], mat[maxn];
bool vis[maxn];

bool cal(int x, int y)
{
    int t = x + y, last = (int)sqrt(t);
    for(int i = 2; i <= last; i++)
        if(t % i == 0) return 0;
    return 1;
}

bool find(int x)
{
    for(int i = 1; i <= cnt2; i++)
        if(cal(a[x], b[i]) && !vis[i])
        {
            vis[i] = 1;
            if(!mat[i] || find(mat[i]))
            {
                mat[i] = x;
                return 1;
            }
        }
    return 0;
}

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        int t;  cin >> t;
        if(t % 2 == 0) b[++cnt2] = t;
        else a[++cnt1] = t;
        if(t == 1) tot++;
    }
    for(int i = 1; i <= cnt1; i++)
    {
        memset(vis, 0, sizeof(vis));
        if(find(i))
        {
            ans++;
            if(a[i] == 1) tot--;
        }
    }
    cout << ans + (int)(tot / 2) << endl;
}

Guess you like

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