0.题目

先放一下这一题的题目:

题目描述

您将获得一个n行m列的棋盘。棋盘的每个格子都包含一个数字 0 或 1。在一次移动中,我们可以选择棋盘的某一行,并循环地将其值向左移动一个单元格,或向右移动一个单元格。

将表格行循环向右移动一个单元格意味着将每个单元格(最后一个单元格除外)的值移动到右侧相邻单元格,并将最后一个单元格的值移动到第一个单元格。行向左的移动类似,但在另一个方向上执行。例如,如果我们循环地将一行"00110"向右移动一个单元格,我们得到一行"00011",但是如果我们向左移动一行"00110"一个单元格,我们得到一行"01100"。

确定使某列仅由数字 1 组成所需的最小移动次数。

输入

第一行包含两个以空格分隔的整数:n(1 ≤ n ≤ 100),m(1 ≤ n ≤ 10000)

然后n行,每行包括m个字符"0"或"1"

输出

输出单个数字:在表格的某些列中仅获得数字 1 所需的最小移动次数。如果无法做到这一点,请输出 -1。

样例输入

3 6
101010
000100
100000

样例输出

3

1.基本思路

先利用bfs计算每一行的0,把那个位置的0变成让那个位置变为1的最小步数,然后一列一列加起来,取最小值即可。

2.AC代码

#include
#include
int main() {
    int n , m;
    scanf("%d",&n);
    scanf("%d",&m);
    int p[101][10001] = {0};
    for (int i = 0; i < n; i++)
    {
        char* input = (char*)calloc(sizeof(char), m + 1);
        scanf("%s", input);
        for (int j = 0; j < m; j++)
        {
            if (input[j] == '0') {
                int offset = 1;
                int left = 0, right = 0;
                while (left==0||right==0) {
                    if (left == 0) {
                        if (j-offset<0) {
                            if (offset>m/2+1) {
                                left = -1;
                            }
                            else {
                                if (p[i][m - j + offset] != 0) {
                                    left = p[i][m - j + offset] + offset;
                                }
                                else if (input[ m - j + offset] == '1') {
                                    right = 1 + offset;
                                }
                            }
                        }
                        else if(p[i][j - offset]!=0) {
                            left = p[i][j - offset] + offset;
                        }
                        else if(input[j-offset] == '1') {
                            right = 1 + offset;
                        }
                    }
                    if(right==0) {
                        if (j + offset >= m) {
                            if (offset > m / 2 + 1) {
                                right = -1;
                            }
                            else {
                                if (p[i][j + offset - m] != 0) {
                                    right = p[i][j + offset - m] + offset;
                                }
                                else if (input[j + offset - m] == '1') {
                                    right = 1 + offset;
                                }
                            }
                        }
                        else if (p[i][j + offset] != 0) {
                            right = p[i][j + offset] + offset;
                        }
                        else if (input[j+offset] == '1') {
                            right = 1 + offset;
                        }
                    }
                    offset++;
                }
                if (left==-1||right==-1) {
                    if (left == -1 && right == -1) {
                        printf("-1");
                        return 0;
                    }
                    else if (left == -1) {
                        p[i][j] = right;
                    }
                    else {
                        p[i][j] = left;
                    }
                }
                else if (left