暑假训练二阶段day2

本文探讨了不同的算法问题,包括湖的数量计算、有序序列中元素出现次数、火蔓延与逃生路径、寻找特定数字的幂次运算以及仅包含0和1的数字序列。通过深度优先搜索(DFS)和广度优先搜索(BFS)等方法,解决了一系列具有挑战性的数学和计算机科学问题。
摘要由CSDN通过智能技术生成

Lake Counting

Due to recent rains, water has pooled in various places in Farmer John's field, which is represented by a rectangle of N x M (1 <= N <= 100; 1 <= M <= 100) squares. Each square contains either water ('W') or dry land ('.'). Farmer John would like to figure out how many ponds have formed in his field. A pond is a connected set of squares with water in them, where a square is considered adjacent to all eight of its neighbors.

Given a diagram of Farmer John's field, determine how many ponds he has.

Input
* Line 1: Two space-separated integers: N and M

* Lines 2..N+1: M characters per line representing one row of Farmer John's field. Each character is either 'W' or '.'. The characters do not have spaces between them.

Output
* Line 1: The number of ponds in Farmer John’s field.
Sample Input

10 12
W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.

Sample Output

3

Hint
OUTPUT DETAILS:

There are three ponds: one in the upper left, one in the lower left,and one along the right side.

和昨天oil一样 不赘述了

include<iostream>
#include<queue>

using namespace std;

const int N = 1e2 + 10;

string s[N];
int dx[] = {0, 1, 0, -1, 1, 1, -1, -1};
int dy[] = {1, 0, -1, 0, -1, 1, -1, 1};
int n, m;

void dfs(int x, int y) {
        s[x][y] = '.';
    for (int i = 0; i < 8; i++) {
        if (n > x + dx[i] && m > y + dy[i] && x + dx[i] >= 0 && y + dy[i] >= 0 && s[x + dx[i]][y + dy[i]] == 'W' ) {
            dfs(x + dx[i], y + dy[i]);
        }
    }
}

int main(void) {
    while (cin >> n >> m && n && m) {
        for (int i = 0; i < n; i++) {
            cin >> s[i];
        }
        int ans = 0;
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++) {
                if (s[i][j] == 'W') {
                    dfs(i, j);
                    ans++;
                }
            }
        cout << ans << endl;
    }
    return 0;
}

Binary Search

Search II

You are given a sequence of n integers S and a sequence of different q integers T. Write a program which outputs C, the number of integers in T which are also in the set S.
Input

In the first line n is given. In the second line, n integers are given. In the third line q is given. Then, in the fourth line, q integers are given.
Output

Print C in a line.
Constraints

Elements in S is sorted in ascending order
n ≤ 100000
q ≤ 50000
0 ≤ an element in S ≤ 109
0 ≤ an element in T ≤ 109

Sample Input 1

5
1 2 3 4 5
3
3 4 1

Sample Output 1

3

Sample Input 2

3
1 2 3
1
5

Sample Output 2

0

Sample Input 3

5
1 1 2 2 3
2
1 2

Sample Output 3

2

Notes

与题目一样 就是二分搜索

#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;
vector<int> a;

int main(void) {
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        a.push_back(x);
    }
    int q, ans = 0;
    cin >> q;
    for (int i = 0; i < q; i++) {
        int x;
        cin >> x;
        if (binary_search(a.begin(), a.end(), x))
            ans++;
    }
    cout << ans << endl;
    return 0;
}

Fire!

Joe works in a maze. Unfortunately, portions of the maze have
caught on fire, and the owner of the maze neglected to create a fire
escape plan. Help Joe escape the maze.
Given Joe’s location in the maze and which squares of the maze
are on fire, you must determine whether Joe can exit the maze before
the fire reaches him, and how fast he can do it.
Joe and the fire each move one square per minute, vertically or
horizontally (not diagonally). The fire spreads all four directions
from each square that is on fire. Joe may exit the maze from any
square that borders the edge of the maze. Neither Joe nor the fire
may enter a square that is occupied by a wall.
Input
The first line of input contains a single integer, the number of test
cases to follow. The first line of each test case contains the two
integers Rand C, separated by spaces, with 1 ≤R,C≤1000. The
following Rlines of the test case each contain one row of the maze. Each of these lines contains exactly
Ccharacters, and each of these characters is one of:
•#, a wall
•., a passable square
•J, Joe’s initial position in the maze, which is a passable square
•F, a square that is on fire
There will be exactly one J in each test case.
Output
For each test case, output a single line containing ‘IMPOSSIBLE’ if Joe cannot exit the maze before the
fire reaches him, or an integer giving the earliest time Joe can safely exit the maze, in minutes.
Sample Input
2
4 4

#JF#
#…#
#…#
3 3

#J.
#.F
Sample Output
3
IMPOSSIBLE

注意一下火是会向周围扩散的
搜一下火蔓延的的时间 在对人的路径搜索

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>

using namespace std;
string s[1010];
int n, m;
int times[1010][1010];
int d[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
struct node {
    int x;
    int y;
};

queue<node> q, p;

void bfs1() {
    int cnt = 0;
    while (!p.empty()) {
        cnt++;
        int t = p.size();
        while (t--) {
            node f = p.front();
            p.pop();
            for (int i = 0; i < 4; i++) {
                int x = f.x + d[i][0];
                int y = f.y + d[i][1];
                if (x < 0 || y < 0 || x >= n || y >= m || s[x][y] == '#' || s[x][y] == 'F') continue;
                p.push({x, y});
                s[x][y] = 'F';
                times[x][y] = cnt;
            }
        }

    }
}

void bfs2() {
    int ans = 0;
    while (!q.empty()) {
        ans++;
        int t = q.size();
        while (t--) {
            node f = q.front();
            q.pop();
            for (int i = 0; i < 4; i++) {
                int x = f.x + d[i][0];
                int y = f.y + d[i][1];
                if (x < 0 || y < 0 || x >= n || y >= m) {
                    cout << ans << endl;
                    return;
                }
                if (s[x][y] == '#' || s[x][y] == 'J') continue;
                if (s[x][y] == 'F' && times[x][y] <= ans)continue;
                q.push({x, y});
                s[x][y] = 'J';
            }
        }
    }
    cout << "IMPOSSIBLE" << endl;
}

int main(void) {
    int t;
    cin >> t;
    while (t--) {
        memset(times, 0, sizeof(times));
        cin >> n >> m;
        while (!q.empty()) q.pop();
        while (!p.empty()) p.pop();
        for (int i = 0; i < n; i++) {
            cin >> s[i];
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] == 'J') q.push({i, j});
                if (s[i][j] == 'F') p.push({i, j});
            }
        }
        bfs1();
        bfs2();
    }
    return 0;
}

Find a way

 Pass a year learning in Hangzhou, yifenfei arrival hometown Ningbo at finally. Leave Ningbo one year, yifenfei have many people to meet. Especially a good friend Merceki.
Yifenfei’s home is at the countryside, but Merceki’s home is in the center of city. So yifenfei made arrangements with Merceki to meet at a KFC. There are many KFC in Ningbo, they want to choose one that let the total time to it be most smallest.
Now give you a Ningbo map, Both yifenfei and Merceki can move up, down ,left, right to the adjacent road by cost 11 minutes.

Input
The input contains multiple test cases.
Each test case include, first two integers n, m. (2<=n,m<=200).
Next n lines, each line included m character.
‘Y’ express yifenfei initial position.
‘M’ express Merceki initial position.
‘#’ forbid road;
‘.’ Road.
‘@’ KCF
Output
For each test case output the minimum total time that both yifenfei and Merceki to arrival one of KFC.You may sure there is always have a KFC that can let them meet.
Sample Input

4 4
Y.#@
....
.#..
@..M
4 4
Y.#@
....
.#..
@#.M
5 5
Y..@.
.#...
.#...
@..M.
#...#

Sample Output

66
88
66

两遍bfs

#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>

using namespace std;
const int N = 205;

int n, m, a1[N][N], a2[N][N];
int dx[] = {0,1,-1,0};
int dy[] = {1,0,0,-1};
string s[N];

struct node {
    int x, y;
};

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

int bfs1(int x, int y) {
    a1[x][y] = 1;
    queue<node> q;
    node start = {x, y};
    q.push(start);
    while (!q.empty()) {
        node tmp = q.front();
        q.pop();
        for (int i = 0; i < 4; i++) {
            int a = tmp.x + dx[i];
            int b = tmp.y + dy[i];
            if (in(a, b) && s[a][b] != '#' && !a1[a][b]) {
                a1[a][b] = a1[tmp.x][tmp.y] + 1;
                node t = {a, b};
                q.push(t);
            }
        }
    }
}

int bfs2(int x, int y) {
    a2[x][y] = 1;
    queue<node> q;
    node start = {x, y};
    q.push(start);
    while (!q.empty()) {
        node tmp = q.front();
        q.pop();
        for (int i = 0; i < 4; i++) {
            int a = tmp.x + dx[i];
            int b = tmp.y + dy[i];
            if (in(a, b) && s[a][b] != '#' && !a2[a][b]) {
                a2[a][b] = a2[tmp.x][tmp.y] + 1;
                node t = {a, b};
                q.push(t);
            }
        }
    }
}

int main(void) {
    int x, y;
    while (cin >> n >> m) {
        memset(a1,0,sizeof (a1));
        memset(a2,0,sizeof (a2));
        int ans = 0x3f3f3f3f;
        for (int i = 0; i < n; i++) cin >> s[i];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] == 'Y') bfs1(i,j);
            }
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] == 'M') bfs2(i, j);;
            }
        }

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (s[i][j] == '@' && a1[i][j] && a2[i][j])
                    ans = min(ans, (a1[i][j] + a2[i][j] - 2) * 11);
            }
        }
        cout << ans << endl;
    }
    return 0;
}

Power Calculus

Starting with x and repeatedly multiplying by x, we can compute x31 with thirty multiplications:

    x2 = x × x, x3 = x2 × x, x4 = x3 × x, …, x31 = x30 × x.

The operation of squaring can be appreciably shorten the sequence of multiplications. The following is a way to compute x31 with eight multiplications:

    x2 = x × x, x3 = x2 × x, x6 = x3 × x3, x7 = x6 × x, x14 = x7 × x7, x15 = x14 × x, x30 = x15 × x15, x31 = x30 × x.

This is not the shortest sequence of multiplications to compute x31. There are many ways with only seven multiplications. The following is one of them:

    x2 = x × x, x4 = x2 × x2, x8 = x4 × x4, x8 = x4 × x4, x10 = x8 × x2, x20 = x10 × x10, x30 = x20 × x10, x31 = x30 × x.

If division is also available, we can find a even shorter sequence of operations. It is possible to compute x31 with six operations (five multiplications and one division):

    x2 = x × x, x4 = x2 × x2, x8 = x4 × x4, x16 = x8 × x8, x32 = x16 × x16, x31 = x32 ÷ x.

This is one of the most efficient ways to compute x31 if a division is as fast as a multiplication.

Your mission is to write a program to find the least number of operations to compute xn by multiplication and division starting with x for the given positive integer n. Products and quotients appearing in the sequence should be x to a positive integer’s power. In others words, x−3, for example, should never appear.

Input

The input is a sequence of one or more lines each containing a single integer n. n is positive and less than or equal to 1000. The end of the input is indicated by a zero.

Output

Your program should print the least total number of multiplications and divisions required to compute xn starting with x for the integer n. The numbers should be written each in a separate line without any superfluous characters such as leading or trailing spaces.

Sample Input

1
31
70
91
473
512
811
953
0

Sample Output

0
6
8
9
11
9
13
12

思路:用一个数组存每一次操作之后得到的数,剪下枝,迭代加深即可。详见代码

#include<iostream>

using namespace std;
int n, maxn, flag, a[2010];

void dfs(int d) {
    if (d > maxn || a[d] << (maxn - d) < n) return;
    if (a[d] == n) {
        flag = 1;
        return;
    }
    for (int i = d; i >= 0; i--) {
        int t = a[d] + a[i];
        if (t > 0 && t < 2000) {
            a[d + 1] = t;
            dfs(d + 1);
            if (flag) return;
        }
        t = a[d] - a[i];
        if (t > 0 && t < 2000) {
            a[d + 1] = t;
            dfs(d + 1);
            if (flag) return;
        }
    }
}

int main(void) {
    while (cin >> n && n) {
        a[0] = 1;
        flag = 0;
        for (maxn = 0;; maxn++) {
            dfs(0);
            if (flag) break;
        }
        cout << maxn << endl;
    }
    return 0;
}

Find The Multiple

Given a positive integer n, write a program to find out a nonzero multiple m of n whose decimal representation contains only the digits 0 and 1. You may assume that n is not greater than 200 and there is a corresponding m containing no more than 100 decimal digits.

Input
The input file may contain multiple test cases. Each line contains a value of n (1 <= n <= 200). A line containing a zero terminates the input.
Output
For each value of n in the input print a line containing the corresponding value of m. The decimal representation of m must not contain more than 100 digits. If there are multiple solutions for a given value of n, any one of them is acceptable.
Sample Input

2
6
19
0

Sample Output

10
100100100100100100
111111111111111111

题意:输入一个整数,输出一个能整除它的数,这个数很特别,它只包含0和1。

题解:直接搜 注意最大19位

#include <iostream>

using namespace std;

int flag = 0;

void dfs(unsigned long long num, int k,int n) {
    if (flag == 1)return;
    if (num % n == 0) {
        cout << num << endl;
        flag = 1;
        return;
    }
    if (k == 19)return;
    dfs(num * 10, k + 1, n);
    dfs(num * 10 + 1, k + 1, n);
}

int main(void) {
    int n;
    while (cin >> n && n) {
        flag = 0;
        dfs(1, 0, n);
    }
    return 0;

棋盘问题

 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。

Input
输入含有多组测试数据。
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
当为-1 -1时表示输入结束。
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
Output
对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。
Sample Input

2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1

Sample Output

2
1

题解:直接dfs

#include <iostream>

using namespace std;

string s[15];
bool vim[15];
int n, k;
int ans;

int dfs(int r, int sum) {
    if (sum >= k) {
        ans++;
        return 1;
    }
    if (r >= n) return 1;
    for (int i = 0; i < n; i++) {
        if (vim[i] != 1 && s[r][i] == '#') {
            vim[i] = true;
            dfs(r + 1, sum + 1);
            vim[i] = false;
        }
    }
    dfs(r + 1, sum);
}

int main() {

    while (cin >> n >> k) {
        if (n == -1 && k == -1)
            break;
        for (int i = 0; i < n; i++) {
            vim[i] = 0;
            cin >> s[i];
        }
        ans = 0;
        dfs(0, 0);
        cout << ans << endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值