机试指南练习-第六章

机试指南练习总结第四章-枚举

机试指南练习总结第四章-广度优先搜索(BFS)

      常用的广度BFS, 一般使用队列实现,可以用来求最佳值

例6.2:胜利大逃亡

提交OJ

题目描述
Ignatius被魔王抓走了,有一天魔王出差去了,这可是Ignatius逃亡的好机会.

魔王住在一个城堡里,城堡是一个ABC的立方体,可以被表示成A个B*C的矩阵,刚开始Ignatius被关在(0,0,0)的位置,离开城堡的门在(A-1,B-1,C-1)的位置,现在知道魔王将在T分钟后回到城堡,Ignatius每分钟能从一个坐标走到相邻的六个坐标中的其中一个.现在给你城堡的地图,请你计算出Ignatius能否在魔王回来前离开城堡(只要走到出口就算离开城堡,如果走到出口的时候魔王刚好回来也算逃亡成功),如果可以请输出需要多少分钟才能离开,如果不能则输出-1.

输入描述

输入数据的第一行是一个正整数K,表明测试数据的数量.每组测试数据的第一行是四个正整数
A,B,C和T(1<=A,B,C<=50,1<=T<=1000),它们分别代表城堡的大小和魔王回来的时间.
然后是A块输入数据(先是第0,然后是第1,2......),每块输入数据有B行,每行有C个正
整数,代表迷宫的布局,其中0代表路,1代表墙.(如果对输入描述不清楚,可以参考Sample Input
中的迷宫描述,它表示的就是上图中的迷宫)

特别注意:本题的测试数据非常大,请使用scanf输入,我不能保证使用cin能不超时.在本OJ上请使用Visual C++提交.

输出描述:

对于每组测试数据,如果Ignatius能够在魔王回来前离开城堡,那么请输出他最少需要多少分钟,否则输出-1.

示例1

输入:

1
3 3 4 20
0 1 1 1
0 0 1 1
0 1 1 1
1 1 1 1
1 0 0 1
0 1 1 1
0 0 0 0
0 1 1 0
0 1 1 0

输出:

11

解题思路
这题思路非常简单,就是DFS,但是需要细节,注意两个细节,首先不需要遍历已经遍历过的点(要不然会MLE), 第二点是考虑出口也为墙的情况

#include <iostream>
#include <stdio.h>
#include <queue>

#define MAX 55

using namespace std;

int data[MAX][MAX][MAX];

struct Node
{
    int x, y, z;
    int depth;
};

int m[6][3] =
{
    1, 0, 0,
    -1, 0, 0,
    0, 1, 0,
    0, -1, 0,
    0, 0, 1,
    0, 0, -1
};

queue<struct Node> qu;

int BFS(int a, int b, int c)
{
    int i;
    while(!qu.empty())
        qu.pop();
    struct Node now;
    struct Node temp;
    now.x = now.y = now.z = now.depth = 0;
    qu.push(now);
    data[0][0][0] = -1;
    while(!qu.empty())//????
    {
        //printf("queue.size = %d\n", qu.size());
        now = qu.front();
        qu.pop();
        for(i=0; i<6; i++)
        {
            temp.x = now.x + m[i][0];
            temp.y = now.y + m[i][1];
            temp.z = now.z + m[i][2];
            temp.depth = now.depth + 1;
            if(temp.x == a-1 && temp.y == b-1 && temp.z == c-1 && data[temp.x][temp.y][temp.z] == 0)
                return temp.depth;
            if(temp.x >= 0 && temp.x <= a-1 && temp.y >= 0 && temp.y <= b-1 && temp.z >= 0 && temp.z <= c-1 )
            {
                if(data[temp.x][temp.y][temp.z] == 0)
                {
                    data[temp.x][temp.y][temp.z] = -1;
                    qu.push(temp);
                }
            }
        }
    }
    return -1;
}

int main()
{
    int a, b, c, t, i, j, k, x, n;
    scanf("%d", &n);
    for(i=0; i<n; i++)
    {
        scanf("%d%d%d%d", &a, &b, &c, &t);
        //printf("%d %d %d %d\n", a, b, c, t);
        for(j=0; j<a; j++)
        {
            for(k=0; k<b; k++)
            {
                for(x=0; x<c; x++)
                {
                    //printf("inner %d %d %d\n", j, k, x);
                    scanf("%d", &data[j][k][x]);
                }
            }
        }
        int res = BFS(a, b, c);
        if(res <= t && res != -1)
            printf("%d\n", res);
        else
            printf("-1\n");
    }
    return 0;
}

例6.3:非常可乐

提交OJ

题目描述
大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"。
输入描述

三个整数 : S 可乐的体积 , N 和 M是两个杯子的容量,以"0 0 0"结束。

输出描述:

如果能平分的话请输出最少要倒的次数,否则输出"NO"

示例1

输入:

7 4 3
4 1 3
0 0 0

输出:

NO
3

解题思路

这题比较难是是确定状态,一开始理解题意时认为边倒边喝也是允许的,这样就把问题复杂化了,同时在本题中必须有两个瓶子中的可乐同时达到s/2,(例如样例2中,1,1,2状态不能算是达到目标)

#include <iostream>
#include <stdio.h>
#include <queue>
#include <string.h>

#define MAX 101

using namespace std;

//题意必须有两个瓶子同时为s/2,只有一个不行

struct state
{
    int a, b, c, t;
};

bool mark[MAX][MAX][MAX];
queue<struct state>qu;

void A2B(int sa, int sb, int &a, int &b)
{
    if((sb - b) >= a)
    {
        b += a;
        a = 0;
    }
    else
    {
        a = a - (sb - b);
        b = sb;
    }
}

int bfs(int s, int n, int m)
{
    memset(mark, 0, sizeof(mark));
    struct state now;
    struct state* nowP;
    struct state temp;
    struct state* tempP;
    mark[s][0][0] = true;
    now.a = s;
    now.b = 0;
    now.c = 0;
    now.t = 0;
    while(!qu.empty())
        qu.pop();
    qu.push(now);
    while(!qu.empty())
    {
        now = qu.front();
        nowP = &now;
        qu.pop();
        //printf("now: a = %d, b = %d, c = %d, t = %d\n", now.a, now.b, now.c, now.t);
        if(now.a != 0)
        {
            //a2b
            tempP = &temp;
            memcpy(tempP, nowP, sizeof(struct state));
            A2B(s, n, temp.a, temp.b);
            temp.t = now.t + 1;
            if((temp.a == s/2 && temp.b == s/2) || (temp.a == s/2 && temp.c == s/2) || (temp.c == s/2 && temp.b == s/2) )
            {
                return temp.t;
            }
            if(mark[temp.a][temp.b][temp.c] == false)
            {
                qu.push(temp);
                mark[temp.a][temp.b][temp.c] = true;
            }
            //a2c
            memcpy(tempP, nowP, sizeof(struct state));
            A2B(s, m, temp.a, temp.c);
            temp.t = now.t + 1;
            if((temp.a == s/2 && temp.b == s/2) || (temp.a == s/2 && temp.c == s/2) || (temp.c == s/2 && temp.b == s/2))
            {
                return temp.t;
            }
            if(mark[temp.a][temp.b][temp.c] == false)
            {
                qu.push(temp);
                mark[temp.a][temp.b][temp.c] = true;
            }
        }
        if(now.b != 0)
        {
            //b2a
            tempP = &temp;
            memcpy(tempP, nowP, sizeof(struct state));
            A2B(n, s, temp.b, temp.a);
            temp.t = now.t + 1;
            if((temp.a == s/2 && temp.b == s/2) || (temp.a == s/2 && temp.c == s/2) || (temp.c == s/2 && temp.b == s/2))
            {
                return temp.t;
            }
            if(mark[temp.a][temp.b][temp.c] == false)
            {
                qu.push(temp);
                mark[temp.a][temp.b][temp.c] = true;
            }
            //b2c
            memcpy(tempP, nowP, sizeof(struct state));
            A2B(n, m, temp.b, temp.c);
            temp.t = now.t + 1;
            if((temp.a == s/2 && temp.b == s/2) || (temp.a == s/2 && temp.c == s/2) || (temp.c == s/2 && temp.b == s/2))
            {
                return temp.t;
            }
            if(mark[temp.a][temp.b][temp.c] == false)
            {
                qu.push(temp);
                mark[temp.a][temp.b][temp.c] = true;
            }
        }
        if(now.c != 0)
        {
            //c2a
            tempP = &temp;
            memcpy(tempP, nowP, sizeof(struct state));
            A2B(m, s, temp.c, temp.a);
            temp.t = now.t + 1;
            if((temp.a == s/2 && temp.b == s/2) || (temp.a == s/2 && temp.c == s/2) || (temp.c == s/2 && temp.b == s/2))
            {
                return temp.t;
            }
            if(mark[temp.a][temp.b][temp.c] == false)
            {
                qu.push(temp);
                mark[temp.a][temp.b][temp.c] = true;
            }
            //c2b
            memcpy(tempP, nowP, sizeof(struct state));
            A2B(m, n, temp.c, temp.b);
            temp.t = now.t + 1;
            if((temp.a == s/2 && temp.b == s/2) || (temp.a == s/2 && temp.c == s/2) || (temp.c == s/2 && temp.b == s/2))
            {
                return temp.t;
            }
            if(mark[temp.a][temp.b][temp.c] == false)
            {
                qu.push(temp);
                mark[temp.a][temp.b][temp.c] = true;
            }
        }

    }
    return -1;
}

int main()
{
    int s, n, m;
    while(scanf("%d%d%d", &s, &n, &m) != EOF)
    {
        if(s == 0 && n == 0 && m == 0)
            break;
        if(s % 2 == 1)
        {
            printf("NO\n");
            continue;
        }
        int res = bfs(s, n, m);
        if(res != -1)
            printf("%d\n", res);
        else
            printf("NO\n");
    }
    return 0;
}

机试指南练习总结第四章-递归

例6.4:汉诺塔III

提交OJ

题目描述
约19世纪末,在欧州的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下、由小到大顺序串着由64个圆盘构成的塔。目的是将最左边杆上的盘全部移到右边的杆上,条件是一次只能移动一个盘,且不允许大盘放在小盘的上面。
现在我们改变游戏的玩法,不允许直接从最左(右)边移到最右(左)边(每次移动一定是移到中间杆或从中间移出),也不允许大盘放到下盘的上面。
Daisy已经做过原来的汉诺塔问题和汉诺塔II,但碰到这个问题时,她想了很久都不能解决,现在请你帮助她。现在有N个圆盘,她至少多少次移动才能把这些圆盘从最左边移到最右边?

输入描述

包含多组数据,每次输入一个N值(1<=N=35)

输出描述:

对于每组数据,输出移动最小的次数。

示例1

输入:

1
3
12

输出:

2
26
531440

解题思路

本题思路就是move(A, B, N-1) ->move(B, C, N-1)->move(A, B, 1)->move(C, B, N-1)->move(B, A, N-1)->move(B, C, 1)->move(A, B, N-1) ->move(B, C, N-1)。其中move(A, B, N-1) + move(B, C, N-1)等于F(N-1), 所以F(N) = 3 * F(N-1) + 2

#include <iostream>
#include <stdio.h>

using namespace std;

long long F(int n)
{
    if(n == 1)
        return 2;
    else
        return 3 * F(n - 1) + 2;
}

int main()
{
    int n;
    while(scanf("%d", &n) != EOF)
    {
        long long res = F(n);
        printf("%I64d\n", res);
    }
    return 0;
}

例6.5:Prime Ring Problem

提交OJ

题目描述
A ring is compose of n circles as shown in diagram. Put natural number 1, 2, …, n into each circle separately, and the sum of numbers in two adjacent circles should be a prime.

Note: the number of first circle should always be 1.
在这里插入图片描述

输入描述

n (0 < n < 20)

输出描述:

The output format is shown as sample below. Each row represents a
series of circle numbers in the ring beginning from 1 clockwisely and 
anticlockwisely. 
The order of numbers must satisfy the above requirements. Print solutions in lexicographical order.
You are to write a program that completes above process.
Print a blank line after each case.

示例1

输入:

6
8

输出:

Case 1:
1 4 3 2 5 6
1 6 5 2 3 4

Case 2:
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2

解题思路

解题思路就是回溯法,DFS,在放入一个数之前检查它与前一个数之和是否为素数,当放入n个数之后再检查一遍最后一个数和第一个数之和是否为素数。其中需要特别注意的是,当n为奇数的时候肯定得不到结果,需要直接输出,而不是再进行回溯,要不然会TLE。我改了之后一直WA,但是看DFS的逻辑根本没错,找了半天,发现是当n为奇数那里,我的cmt没有加1…,所以写代码的时候一定要特别细心。

#include <iostream>
#include <stdio.h>
#include <string.h>

#define MAX 22
#define MAXX 44

using namespace std;

//vector的拷贝问题
//vector的清空问题
//超时问题

int res[MAX];
bool mark[MAX];
int n;
bool prime[MAXX];

void init()
{
    int i, j;
    memset(prime, 1, sizeof(prime));
    prime[1] = false;
    for(i=2; i<MAXX; i++)
    {
        if(prime[i] == true)
        {
            for(j=i*i; j<MAXX; j+=i)
            {
                prime[j] = false;
            }
        }
    }
}

void DFS(int x)
{
    int i;
    if(x == n)
    {
        if(prime[res[x] + res[1]] == false)
            return;

        for(i=1; i<=x; i++)
        {

            if(i == x)
            {
                t++;
                printf("%d\n", res[i]);
            }

            else
                printf("%d ", res[i]);
        }

        return;
    }
    else
    {
        for(i=1; i<=n; i++)
        {
            if(mark[i] == false && prime[i + res[x]] == true)
            {
                res[x+1] = i;//注意
                mark[i] = true;
                DFS(x+1);
                mark[i] = false;
            }
        }
    }
    return;
}

int main()
{
    int cmt = 1;
    init();
    while(scanf("%d", &n) != EOF)
    {
        if(n % 2 == 1)
        {
            printf("Case %d:\n", cmt++);
            printf("\n");
            continue;
        }
        memset(mark, 0, sizeof(mark));
        mark[1] = true;
        res[1] = 1;
        printf("Case %d:\n", cmt);
        DFS(1);
        printf("\n");
        cmt++;
    }
    return 0;
}

其他需要注意的知识点

  1. vector的基础使用问题,vector以使用其他vector或者数组来进行初始化。参考博客:https://blog.csdn.net/wkq0825/article/details/82255984
  2. vector sizecapacity的区别,size指明的是vector当前存储的元素的个数,使用eraseclear可以是vectorsize归零,而capacityvector预先分配的存储空间,这个存储空间只增长不减少。详细区别可见博客:https://blog.csdn.net/pengshengli/article/details/86287794
  3. vectorerase的使用,a.erase(a.begin(), a.begin() + 2);可以清除a中0~2的元素,同时后面的元素会自动补位
  4. vectorinsert的使用,a.insert(a.begin()+1,5); 会在a的第1个元素(从第0个算起)后面插入数值5,如a为1,2,3,4,插入元素后为1,5,2,3,4
  5. vector的清空问题,由第2点我们可知,vector分配的空间只增长不减少,使用clearerase不能清空预先分配的内存,不回收内存。我们可以使用swap来清空vector,如下vector <int>().swap(vecInt);。参考博客:https://blog.csdn.net/sinat_18811413/article/details/104592921

例6.6:Oil Deposits

提交OJ

题目描述
The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots. It then analyzes each plot separately, using sensing equipment to determine whether or not the plot contains oil. A plot containing oil is called a pocket. If two pockets are adjacent, then they are part of the same oil deposit. Oil deposits can be quite large and may contain numerous pockets. Your job is to determine how many different oil deposits are contained in a grid

输入描述

The input file contains one or more grids. Each grid begins with a line
containing m and n, the number of rows and columns in the grid, 
separated by a single space. If m = 0 it signals the end of the input;
otherwise 1 <= m <= 100 and 1 <= n <= 100. Following this are m lines
of n characters each (not counting the end-of-line characters). 
Each character corresponds to one plot, and is either `*', representing
the absence of oil, or `@', representing an oil pocket.

输出描述:

For each grid, output the number of distinct oil deposits. 
Two different pockets are part of the same oil deposit if they are
adjacent horizontally, vertically, or diagonally. An oil deposit will
not contain more than 100 pockets.

示例1

输入:

1 1
*
3 5
*@*@*
**@**
*@*@*
1 8
@@****@*
5 5 
****@
*@@*@
*@**@
@@@*@
@@**@
0 0 

输出:

0
1
2
2

解题思路

本题还是使用DFS进行求解,需要注意的是在对一个点进行遍历之后不需要回复状态,因为mark[i][j] = true就标志着该点已经在某个oil deposits中,而本题就是需要通过这种状态来求解一共有多少个不同的oil deposits。

#include <iostream>
#include <stdio.h>
#include <string.h>

#define MAX 102

using namespace std;

char data[MAX][MAX];
bool mark[MAX][MAX];

int m, n;

int mov[8][2] =
{
    1, 0,
    -1, 0,
    0, 1,
    0, -1,
    1, 1,
    -1, -1,
    -1, 1,
    1, -1

};

bool DFS(int x, int y)
{
    if(data[x][y] == '*' || mark[x][y] == true)
        return false;
    int i;
    mark[x][y] = true;
    for(i=0; i<8; i++)
    {
        if(x + mov[i][0] >= 1 && x + mov[i][0] <= m && y + mov[i][1] >= 1 && y + mov[i][1] <= n)
        {
            DFS(x + mov[i][0], y + mov[i][1]);
        }
    }
    return true;
}


int main()
{
    int i, j;
    while(scanf("%d", &m) != EOF)
    {
        if(m == 0)
            break;
        memset(mark, 0, sizeof(mark));
        scanf("%d", &n);
        for(i=1; i<=m; i++)
        {
            for(j=1; j<=n; j++)
            {
                while(1)
                {
                    scanf("%c", &data[i][j]);
                    if(data[i][j] == '*' || data[i][j] == '@')
                        break;
                }
            }
        }
        int res = 0;
        for(i=1; i<=m; i++)
        {
            for(j=1; j<=n; j++)
            {
                if(DFS(i, j))
                    res++;
            }
        }
        printf("%d\n", res);
    }
    return 0;
}

练习题:全排列

提交OJ

题目描述
给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。 我们假设对于小写字母有’a’ < ‘b’ < … < ‘y’ < ‘z’,而且给定的字符串中的字母已经按照从小到大的顺序排列。

输入描述

输入只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在16之间。

输出描述:

输出这个字符串的所有排列方式,每行一个排列。要求字母序比较小的排列在前面。字母序如下定义:
已知S = s1s2...sk , T = t1t2...tk,则S < T 等价于,存在p (1 <= p <= k),使得
s1 = t1, s2 = t2, ..., sp - 1 = tp - 1, sp < tp成立。

每组样例输出结束后要再输出一个回车。

示例1

输入:

abc

输出:

abc
acb
bac
bca
cab
cba

解题思路

直接DFS就能求解,但是需要注意的是,题目中说输入的字符串中的字母都已经按大小排序好了,但是测试用例并没有,需要在代码中对字符串sort,要不然无法AC

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>

#define MAX 10

using namespace std;

char str[MAX];
char res[MAX];
bool mark[MAX];
int s;

void DFS(int x)
{
    int i;
    if(x == s-1)
    {
        for(i=0; i<s; i++)
            printf("%c", res[i]);
        printf("\n");
        return;
    }
    else
    {
        for(i=0; i<s; i++)
        {
            if(mark[i] == false)
            {
                mark[i] = true;
                res[x+1] = str[i];
                DFS(x+1);
                mark[i] = false;
            }
        }
    }
}


int main()
{
    while(scanf("%s", str) != EOF)
    {
        int i;
        memset(mark, 0, sizeof(mark));
        s = strlen(str);
        sort(str, str + s);
        for(i=0; i<s; i++)
        {
            mark[i] = true;
            res[0] = str[i];
            DFS(0);
            mark[i] = false;
        }
    }
    return 0;
}

机试指南练习总结第四章-深度优先搜索(DFS)

例6.7:Tempter of the Bone

提交OJ

题目描述
The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze began to shake, and the doggie could feel the ground sinking. He realized that the bone was a trap, and he tried desperately to get out of this maze.

The maze was a rectangle with sizes N by M. There was a door in the maze. At the beginning, the door was closed and it would open at the T-th second for a short period of time (less than 1 second). Therefore the doggie had to arrive at the door on exactly the T-th second. In every second, he could move one block to one of the upper, lower, left and right neighboring blocks. Once he entered a block, the ground of this block would start to sink and disappear in the next second. He could not stay at one block for more than one second, nor could he move into a visited block. Can the poor doggie survive? Please help him.

输入描述

The input consists of multiple test cases. 
The first line of each test case contains three integers N, M, and T 
(1 < N, M < 7; 0 < T < 50), which denote the sizes of the maze and the 
time at which the door will open, respectively. The next N lines give 
the maze layout, with each line containing M characters. A character is 
one of the following:

'X': a block of wall, which the doggie cannot enter;
'S': the start point of the doggie;
'D': the Door; or
'.': an empty block.

The input is terminated with three 0's. This test case is not to be processed.

输出描述:

For each test case, print in one line "YES" if the doggie can survive,
 or "NO" otherwise.

示例1

输入:

4 4 5
S.X.
..X.
..XD
....
3 4 5
S.X.
..X.
...D
0 0 0

输出:

NO
YES

解题思路

本题也是使用DFS进行搜索,但是需要剪枝,要不然会TLE,这个剪枝方法不是特别好想。因为每次只能移动一格,所以移动时间就等于移动的步数,同时每移动一次横纵坐标之和就加1或者减1,这样的话,如果起点和终点的横纵坐标之和的奇偶性相同,则必须移动偶数步才能到达终点,反之则必须移动奇数步才能到达终点,可以运用这个特性进行剪枝。每次在使用DFS之前最好都先思考是否可以进行剪枝加快算法速度。

#include <iostream>
#include <stdio.h>
#include <string.h>

#define MAX 10

//超时,注意剪枝

using namespace std;

char data[MAX][MAX];
bool mark[MAX][MAX];

int mov[4][2] =
{
    1,0,
    -1,0,
    0,1,
    0,-1
};

int n, m, t;

bool DFS(int x, int y, int time)
{
    int i;
    if(time > t)
        return false;
    if(data[x][y] == 'D' && time == t)
        return true;
    bool res = false;
    mark[x][y] = true;
    for(i=0; i<4; i++)
    {
        if(x + mov[i][0] >= 0 && x + mov[i][0] < n && y + mov[i][1] >= 0 && y + mov[i][1] < m && data[x + mov[i][0]][y + mov[i][1]] != 'X' && mark[x + mov[i][0]][y + mov[i][1]] == false)
        {
            res = res || DFS(x + mov[i][0], y + mov[i][1], time + 1);
            if(res == true)
                break;
        }
    }
    mark[x][y] = false;
    return res;
}

int main()
{
    int i, j, ssum, esum;
    while(scanf("%d%d%d", &n, &m, &t) != EOF)
    {
        memset(mark, 0, sizeof(mark));
        if(n == 0 && m == 0 && t == 0)
            break;
        for(i=0; i<n; i++)
        {
            for(j=0; j<m; j++)
            {
                while(1)
                {
                    scanf("%c", &data[i][j]);
                    if(data[i][j] == 'X' || data[i][j] == 'S' || data[i][j] == 'D' || data[i][j] == '.')
                    {
                        if(data[i][j] == 'S')
                            ssum = i + j;
                        if(data[i][j] == 'D')
                            esum = i + j;
                        break;
                    }
                }
            }
        }
        if((ssum % 2 == esum %2) && (t % 2 == 1) || (ssum % 2 != esum %2) && (t % 2 == 0))
        {
            printf("NO\n");
            continue;
        }
        int res;
        for(i=0; i<n; i++)
        {
            for(j=0; j<m; j++)
            {
                if(data[i][j] == 'S')
                {
                    mark[i][j] = true;
                    res = DFS(i, j, 0);
                    break;
                }
            }
        }
        if(res)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值