在给定矩阵中找到循环总数

时间:2019-08-03 21:11:22

标签: c++ algorithm data-structures graph adjacency-matrix

加里的木板尺寸为NxM。板上的每个单元都是一个彩色圆点。只有26种颜色以大写拉丁字符(即A,B,...,Z)表示。现在加里感到无聊,想玩游戏。该游戏的关键是找到一个包含相同颜色点的循环。形式上,当且仅当满足以下条件时,我们才将点d1,d2,...,dk的序列称为循环: 1.这k个点不同:如果i≠j,则di与dj不同。 2. k至少为4。 3.所有点都属于相同的颜色。 4.对于所有1≤i≤k-1:di和di + 1相邻。同样,dk和d1也应该相邻。如果x和y单元共享一条边,则它们称为相邻单元。

输入格式 第1行:两个整数N和M,即木板的行数和列数

后N行:由M个字符组成的字符串,表示每行中点的颜色。每个字符都是大写的拉丁字母。

输出格式:如果有循环,则返回1,否则返回0

  1. 我认为我将创建一个“已访问”矩阵,如果已对索引进行了标记,它将为索引标记1。
  2. 然后,我将遍历每个元素并将其传递给新函数,该函数将递归工作,如果存在循环则返回1。 3.我将传递访问矩阵,原始矩阵的维数(与访问矩阵相同),int i,int j(i和j是原始索引通过我们的原始函数传递给该函数,并且在递归过程中不会改变调用),int p,int q(p和q继续更改为其他合格索引),count(如果count> = 4并且p和q与i和j相邻)返回1;
  3. 我还将创建一个符合条件的函数,以检查给定的索引是否不超出范围。

我也需要有关方法的帮助。我想我使这个问题复杂化了。请帮助我,例如我应该朝哪个方向思考。我已经花了超过两天的时间。

Solution.h


int x[4]={0,0,1,-1};
int y[4]={1,-1,0,0};


int iseligible(char board[][MAXN], int n, int m, int i, int j, int** visited){

    if (i<m && j<n && i>=0 && j>=0 && visited[i][j]==0)
        return 1;

    return 0;
}

int solver(char board[][MAXN], int n, int m,int i, int j,int p, int q, int count, int** visited){

    //Base case-if our pq are surrounding of ij and count>=4

    for(int k=0;k<4;k++){

        if(count>=4 && p==i+x[k] && q==j+y[k]){
            return 1;
        }
    }

    for(int k=0;k<4;k++){
        if(iseligible(board, n, m, i+x[k], j+y[k], visited)==1){

            visited[i+x[k]][j+y[k]]==1;

            if(solver(board, n, m, i+x[k], j+y[k], i+x[k], j+y[k], 1, visited)){    
                return 1;
            }

            if(solver(board, n, m, i, j, i+x[k], j+y[k], count+1, visited)==1){
                return 1;   
            }

        }
    }


    return 0;
}


int solve(char board[][MAXN],int n, int m)
{
    int result=0;
    int** visited = new int*[m];

    for(int i=0;i<m;i++){
        visited[i] = new int[n];

        for(int j = 0; i<n; j++){
            visited[i][j] = 0;

        }
    }

    for(int i = 0;i<n;i++){
        for(int j = 0;j<m;j++){
            visited[i][j]=1;
            if(solver(board, n, m, i, j, i, j, 1, visited) == 1){
                return 1;
            }
        }
    }

    return 0;

}


下面已完成输入处理,无法更改

#include<bits/stdc++.h>
using namespace std;
#define MAXN 51
#include "solution.h"
int main()
{
    int N,M,i;
    char board[MAXN][MAXN];
    cin>>N>>M;
    for(i = 0;i < N; i++){
        cin>>board[i];
    }
    cout<<solve(board,N,M)<<endl;
}

输入: 3 4 AAAA 澳洲广播公司 AAAA

预期输出: 1

我得到的输出: 运行时错误

4 个答案:

答案 0 :(得分:0)

cx=[1,-1,0,0]
cy=[0, 0,1,-1]

def path_helper(matrix,visited,x,y,rows,cols,chars,formx,formy):
    if x>rows or y>cols:
        return 0

    if visited[x][y]==1:
        return 1

    if matrix[x][y]!=chars:
        return 0

    visited[x][y] = 1

    for i in range(0,4):
        dx=x+cx[i]
        dy=y+cy[i]
        if(dx>=0 and dx<=rows and dy>=0 and dy<=cols and matrix[dx][dy]==chars and dx!=formx and dy!=formy):
            if path_helper(matrix,visited,dx,dy,rows,cols,chars,x,y):
                return 1
        else:
            continue
        return 0


def s(graph,rows,cols):
    x,y = (0,0)
    result = 0
    r = max(rows,cols)
    visited = [[0 for i in range(r+1)]for j in range(r+1)]
    for i in range(0,len(graph)):
        for j in range(0,len(graph[0])):
            chars = graph[i][j]
            if visited[i][j]!=1:
                result = path_helper(graph,visited,i,j,rows-1,cols-1,chars,-1,-1)
                if result:
                    break
    return result



x,y = [int(i) for i in input().split()]
graph = []
for i in range(0,x):
    m = []
    l = input()
    for i in l:
        m.append(i)    
    graph.append(m)

print(s(graph,len(graph),len(graph[0])))

这里的窍门是formx和formy参数,它们避免了不必要的Callas。

`

答案 1 :(得分:0)

int xdir[4] = {1,-1,0,0};
int ydir[4] = {0,0,1,-1};
int visited[MAXN][MAXN];

bool eligible(char board[][MAXN], int n, int m, int i, int j, char curr){
    if(i>=0 && j>=0 && i<n && j<m && board[i][j]==curr)
        return true;
    return false;
}

int path_helper(char board[][MAXN], int n, int m, int i, int j, int fromx, int fromy, char curr){
    if(i>n || j>m)
        return 0;
    if(visited[i][j] == 1)
        return 1;
    if(board[i][j] != curr)
        return 0;

    visited[i][j] = 1;
    for(int k = 0 ; k < 4 ; k++){
        int dx = i + xdir[k];
        int dy = j + ydir[k];
        if(eligible(board,n,m,dx,dy,curr) && (dx!=fromx || dy!=fromy)){
            if(path_helper(board, n, m, dx, dy, i, j, curr) == 1)
                return 1;
        }
    }
    return 0;
}

int solve(char board[][MAXN],int n, int m)
{
    int ans = 0;
    memset(visited,0,sizeof(visited));
    for(int i = 0 ; i < n ; i++){
        for(int j = 0 ; j < m ; j++){
            if(visited[i][j] != 1){
                char curr = board[i][j];
                ans = path_helper(board, n, m, i, j, -1, -1, curr);
                if(ans==1)
                    return 1;
            }
        }
    }
    return ans;
}

答案 2 :(得分:0)

我认为这会有所帮助。

#define li long int
li yes,N,M;
li check[50][50];

void dfs(char board[][MAXN],li i,li j,li i0,li j0){
    check[i][j]=1;
    if(!(i==i0 && j+1==j0) && j+1<M){
        if(board[i][j]==board[i][j+1]){
            if(check[i][j+1]){
                yes=1;
                return;
            }
            dfs(board,i,j+1,i,j);
        }
        if(yes) return;
    }
    if(yes) return;
    if(!(i+1==i0 && j==j0)&& i+1<N){
        if(board[i+1][j]==board[i][j]){
            if(check[i+1][j]){
                yes=1;
                return;
            }
            dfs(board,i+1,j,i,j);
        }
        if(yes) return;
    }
    if(yes) return;
    if(!(i==i0 && j-1==j0)&& j-1>=0){
        if(board[i][j-1]==board[i][j]){
            if(check[i][j-1]){
                yes=1;
                return;
            }
            dfs(board,i,j-1,i,j);
        }
        if(yes) return;
    }
    if(yes) return;
    if(!(i-1==i0 && j==j0)&& i-1>=0){
        if(board[i-1][j]==board[i][j]){
            if(check[i-1][j]){
                yes=1;
                return;
            }
            dfs(board,i-1,j,i,j);
        }
        if(yes) return;
    }
    if (yes) return;
    check[i][j]=2;

}

int solve(char board[][MAXN],int n, int m)
{
    // Write your code here.
    N=n;
    M=m;
    memset(check,0,sizeof(check));
    yes=0;
    for (li i=0;i<n;i++){
        for (li j=0;j<m;j++){
            if(check[i][j]==0) dfs(board,i,j,-1,-1);
            if(yes) break;
        }
        if(yes) break;
    }
    return yes;
}

答案 3 :(得分:0)

#include <iostream>
#include <vector>
using namespace std;

bool dfs(vector<vector<char>> &board, bool **visited, int i, int j, char e) {
    //e is the parent character we need to check for the cycle
    //below is the check to avoid out of bound call
    if (i < 0 || i >= board.size() || j < 0 || j >= board[i].size() ||
        board[i][j] != e) {
        return false;
    }
    if (visited[i][j]) {
        return true;
    }
    visited[i][j] = 1;
    // below we remove the current vertex temporarily to call the recursive dfs further
    board[i][j] = '.';
    bool exists =
        dfs(board, visited, i - 1, j, e) || dfs(board, visited, i, j - 1, e) ||
        dfs(board, visited, i, j + 1, e) || dfs(board, visited, i + 1, j, e);
    //attach it back
    board[i][j] = e;
    return exists;
}

bool hasCycle(vector<vector<char>> &board, int n, int m) {
    bool **visited = new bool *[n];
    for (int i = 0; i < n; i++) {
        visited[i] = new bool[m];
        for (int j = 0; j < m; j++) {
            visited[i][j] = 0;
        }
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (!visited[i][j] and dfs(board, visited, i, j, board[i][j])) {
                return true;
            }
        }
    }
    return false;
}

int main() {
    int n, m;
    cin >> n >> m;

    vector<vector<char>> board(n, vector<char>(m));

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cin >> board[i][j];
        }
    }

    cout << (hasCycle(board, n, m) ? "true" : "false");
}