搜索1部分题目

1.Red and Black

There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A man is standing on a black tile. From a tile, he can move to one of four adjacent tiles. But he can't move on red tiles, he can move only on black tiles. 

Write a program to count the number of black tiles which he can reach by repeating the moves described above. 

InputThe input consists of multiple data sets. A data set starts with a line containing two positive integers W and H; W and H are the numbers of tiles in the x- and y- directions, respectively. W and H are not more than 20. 

There are H more lines in the data set, each of which includes W characters. Each character represents the color of a tile as follows. 

'.' - a black tile 
'#' - a red tile 
'@' - a man on a black tile(appears exactly once in a data set) 
OutputFor each data set, your program should output a line which contains the number of tiles he can reach from the initial tile (including itself). 

Sample Input

6 9
....#.
.....#
......
......
......
......
......
#@...#
.#..#.
11 9
.#.........
.#.#######.
.#.#.....#.
.#.#.###.#.
.#.#..@#.#.
.#.#####.#.
.#.......#.
.#########.
...........
11 6
..#..#..#..
..#..#..#..
..#..#..###
..#..#..#@.
..#..#..#..
..#..#..#..
7 7
..#.#..
..#.#..
###.###
...@...
###.###
..#.#..
..#.#..
0 0

Sample Output

45
59
6
13

思路:这道题我参考了书本然后用了bfs,在这个矩阵中,点只能往四个方向走,分别是上下左右,所以设置数组dir来实现坐标的变化,check则是判断这个点有没有超出矩阵的大小,结构体就是为了存储这个点的坐标而建立的。
然后是bfs函数,因为题目出发的点也算一个,所以sum初始值为1,然后建立队列,把第一个点压入队列,开始循环一直到队列为空(也就是把矩阵都访问一遍)。对每一个点都进行四次循环,如果周围的点中有可以走的点,num加1,然后把这个点标记为不可走,并把这个点压入队列。如此循环往复,直到队列为空。
ac代码:
#include <iostream>
#include <queue>
using namespace std;
char room[23][23];
int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
int wx,hy,num;
#define check(x,y)(x<wx&&x>=0&&y>=0&&y<hy)
struct node{int x,y;};
void bfs(int dx,int dy){
    num=1;
    queue<node>q;
    node start,next;
    start.x=dx;
    start.y=dy;
    q.push(start);
    while(!q.empty()){
        start=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            next.x=start.x+dir[i][0];
            next.y=start.y+dir[i][1];
            if(check(next.x,next.y)&&room[next.x][next.y]=='.'){
                room[next.x][next.y]='#';
                num++;
                q.push(next);
                
                
                
            }
                
            
        }
    }
    
    
    
    
    
    
    
}
int main(int argc, const char * argv[]) {
    int x,y,dx,dy;
    while(cin>>wx>>hy){
        if(wx==0&&hy==0){
            break;
        }
        for(y=0;y<hy;y++){
            for(x=0;x<wx;x++){
                cin>>room[x][y];
                if(room[x][y]=='@'){
                    dx=x;
                    dy=y;
                }
                    
            }
            
            
            
        }
        num=0;
        bfs(dx,dy);
        cout<<num<<endl;
        
        
        
        
        
    }
    return 0;
}
View Code

2.Catch That Cow

Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.

* Walking: FJ can move from any point X to the points - 1 or + 1 in a single minute
* Teleporting: FJ can move from any point X to the point 2 × X in a single minute.

If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?

Input

Line 1: Two space-separated integers: N and K

Output

Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.

Sample Input

5 17

Sample Output

4

Hint

The fastest way for Farmer John to reach the fugitive cow is to move along the following path: 5-10-9-18-17, which takes 4 minutes.
思路:这道题目也是一道入门的bfs的题目,主要是要额外设置一个标记数组,然后在设置一个步数数组,直接计算走到哪一个数字需要的步数。因为这道题只有三个方向,并且是在一位数组上,所以就直接暴力把每一个压入队列的数字都进行+1,-1和*2操作,然后再把这些也全部压入队列中,然后加入了判断,只要与奶牛位置相同就退出循环输出步数。
ac代码:
#include <iostream>
#include <queue>
using namespace std;
int bfs(int n,int k){
    int flag1[1000001];
    int bs[1000001];
    queue<int>q;
    q.push(n);
    int start=0;
    if(n==k){
        return 0;
    }
    while(!q.empty()){
        start=q.front();
        q.pop();
        if(start+1<1000001&&flag1[start+1]!=1){
            flag1[start+1]=1;
            bs[start+1]=bs[start]+1;
            q.push(start+1);
        }
        if(start+1==k) break;
        if(start-1>=0&&flag1[start-1]!=1){
            flag1[start-1]=1;
            bs[start-1]=bs[start]+1;
            q.push(start-1);
        }
        if(start-1==k) break;
        if(start*2<1000001&&flag1[start*2]!=1){
            flag1[start*2]=1;
            bs[start*2]=bs[start]+1;
            q.push(start*2);
        }
        if(start*2==k) break;
            
            
            
            
        }
    return bs[k];
}
int main(int argc, const char * argv[]) {
    int N,K;
    cin>>N>>K;
    cout<<bfs(N, K)<<endl;
    return 0;
}
View Code

3.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
思路:这道题要找一个数能够整除题目中给的数,这道题目也只有两个方向,从1开始,要不就是*10,要不就是*10+1,利用bfs遍历输出其中最小的一个就行了
ac代码:
#include <iostream>
#include <queue>
using namespace std;
void bfs(long long n,int m){
    queue<long long>q;
    q.push(n);
    while(!q.empty()){
        long long t=q.front();
        q.pop();
        if(t%m==0){
            cout<<t<<endl;
            return ;
        }
        else {q.push(t*10);q.push(t*10+1);}
    }
    
    
    
    
    
    
}

int main(int argc, const char * argv[]) {
    int k;
    bool flag1=true;
    while(flag1){
        cin>>k;
        if(k==0){
            flag1=false;
            break;
        }
        if(k!=0){
            bfs(1,k);
        }
        
        
        
    }
    
    return 0;
}
View Code

4.Prime Path

The ministers of the cabinet were quite upset by the message from the Chief of Security stating that they would all have to change the four-digit room numbers on their offices. 
— It is a matter of security to change such things every now and then, to keep the enemy in the dark. 
— But look, I have chosen my number 1033 for good reasons. I am the Prime minister, you know! 
— I know, so therefore your new number 8179 is also a prime. You will just have to paste four new digits over the four old ones on your office door. 
— No, it’s not that simple. Suppose that I change the first digit to an 8, then the number will read 8033 which is not a prime! 
— I see, being the prime minister you cannot stand having a non-prime number on your door even for a few seconds. 
— Correct! So I must invent a scheme for going from 1033 to 8179 by a path of prime numbers where only one digit is changed from one prime to the next prime. 

Now, the minister of finance, who had been eavesdropping, intervened. 
— No unnecessary expenditure, please! I happen to know that the price of a digit is one pound. 
— Hmm, in that case I need a computer program to minimize the cost. You don't know some very cheap software gurus, do you? 
— In fact, I do. You see, there is this programming contest going on... Help the prime minister to find the cheapest prime path between any two given four-digit primes! The first digit must be nonzero, of course. Here is a solution in the case above. 
1033 
1733 
3733 
3739 
3779 
8779 
8179
The cost of this solution is 6 pounds. Note that the digit 1 which got pasted over in step 2 can not be reused in the last step – a new 1 must be purchased.

Input

One line with a positive number: the number of test cases (at most 100). Then for each test case, one line with two numbers separated by a blank. Both numbers are four-digit primes (without leading zeros).

Output

One line for each case, either with a number stating the minimal cost or containing the word Impossible.

Sample Input

3
思路;这道题目就是将一个质数通过最少的步骤转换成另外一个步数,换一个数字要➕1,然后主要是四个方向的变化,分别为个十百千位的变化,但是要注意的是个位必须是奇数,千位要大于等于1,然后我不会写质数表,就写了一个判断它是不是质数的函数,然后利用bfs就可以解决了
ac代码:
#include <iostream>
#include <string.h>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
#define max 1000000
int bool1[max];
struct node{
    int data;
    int step;
}x,y;
bool judge(int x)//判断是否为素数//
{
    if(x==1||x==0)
        return 0;
    for(int i = 2; i <= sqrt(x); i ++)
    {
        if(x % i == 0)
            return 0;
    }
    return 1;
}
//变化个位:X/10*10+i;变化十位:X/100*100+i*10+X%10;变化百位:X/1000*1000+i*100+i%100;变化千位:i*1000+i%1000;//
void bfs(int n,int m){
    queue<node>q;
    memset(bool1,0,sizeof(bool1));
    bool1[n]=1;
    x.data=n;
    x.step=0;
    q.push(x);
    while(!q.empty()){
        x=q.front();
        q.pop();
        if(x.data==m){
            cout<<x.step<<endl;
            return;
        }
        //个位//
        for(int i=1;i<=9;i=i+2){
            int k=x.data/10*10+i;
            if(judge(k)&&!bool1[k]){
                bool1[k]=1;
                y.data=k;
                y.step=x.step+1;
                q.push(y);
                
                
            }
            
        }
        //十位//
        for(int i=0;i<=9;i++){
            int t=x.data%10;
            int k=x.data/100*100 +i*10+t;
            if(judge(k)&&!bool1[k]){
                bool1[k]=1;
                y.data=k;
                y.step=x.step+1;
                q.push(y);
            }
            
            
        }
        //百位//
        for(int i=0;i<=9;i++){
            int t=x.data%100;
            int k=x.data/1000*1000 +i*100+t;
            if(judge(k)&&!bool1[k]){
                bool1[k]=1;
                y.data=k;
                y.step=x.step+1;
                q.push(y);
            }
            
            
        }
        //千位//
        for(int i=1;i<=9;i++){
            int t=x.data%1000;
            int k=i*1000+t;
            if(judge(k)&&!bool1[k]){
                bool1[k]=1;
                y.data=k;
                y.step=x.step+1;
                q.push(y);
            }
            
            
        }
        
        
        
        
        
        
        
    }
    
    
    

    
    
    
    
    
    
    
    
    return;
    
}


int main(int argc, const char * argv[]) {
    int num;
    int k,l;
    cin>>num;
    while(num--){
        cin>>k>>l;
        bfs(k,l);
        
       
        
        
        
    }
    return 0;
}
View Code

5.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.
思路:这道题就是求一个区域内最大连通子图的数量,然后这道题需要八个方向的变化,因为要判断这个点周围八个区域是不是相应的联通区域,然后利用dfs递归的方式将读到这个点的所有连通区域变成不可以走的范围,然后统计读到几个点就是连通区域的数量
ac代码:
#include <iostream>
#define max 107;
using namespace std;
int dir[8][2]={{-1,0},{1,0},{0,-1},{0,1},{-1,-1},{1,1},{1,-1},{-1,1}};
char a[107][107];
int n,m;
void dfs(int x,int y){
    a[x][y]='.';
    for(int i=0;i<8;i++){
        int x1,y1;
        x1 = x+dir[i][0];
        y1 = y+dir[i][1];
        if(x1>n-1||x1<0||y1<0||y1>m-1){
            continue;
        }
        if(a[x1][y1]=='.'){
            continue;
        }
        dfs(x1,y1);
}
}

    
int main(int argc, const char * argv[]){
    while(cin>>n>>m){
        int sum=0;
        if(n==0||m==0){
            break;
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                cin>>a[i][j];
            }
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(a[i][j]=='W'){
                    dfs(i, j);
                    cout<<i<<j<<endl;
                    sum=sum+1;
                }
            }
        }
        
        
        
        cout<<sum;
        
    }
        
        
        
        
        
        
    return 0;
    }
View Code

 

posted @ 2019-12-05 21:52  林某大帅比  阅读(198)  评论(0编辑  收藏  举报