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;
}