二分确定每个位置要变成1所需的最小移动步数(对于每个位置找相邻最近的1)..为了方便操作..将原列扩展成3*M...

       然后对于1~M的每一列进行统计..得到最小值....


Program:

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<map>
#include<queue>
#include<stack>
#define ll long long
#define oo 2000000000
#define pi acos(-1)
using namespace std;
struct node
{
int num,h[30005];
}a[103];
int n,m,data,dis[103][10005];
char s[103][30005];
int A(int x)
{
if (x<0) return -x;
return x;
}
int main()
{
int i,j,ans;
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++)
{
scanf("%s",s[i]+1);
for (j=1;j<=m;j++) s[i][m+j]=s[i][m*2+j]=s[i][j];
a[i].num=0;
for (j=1;j<=m*3;j++)
if (s[i][j]=='1')
a[i].h[++a[i].num]=j;
}
memset(dis,-1,sizeof(dis));
int l,r,mid,x;
for (i=1;i<=n;i++)
{
if (!a[i].num) break;
for (j=1;j<=m;j++)
{
x=m+j;
l=1; r=a[i].num;
while (r-l>1)
{
mid=(r+l)/2;
if (a[i].h[mid]>=x) r=mid;
else l=mid;
}
if (A(x-a[i].h[l])<A(x-a[i].h[r])) dis[i][j]=A(x-a[i].h[l]);
else dis[i][j]=A(x-a[i].h[r]);
}
}
ans=-1;
for (i=1;i<=m;i++)
{
data=0;
for (j=1;j<=n;j++)
if (dis[j][i]==-1) goto A;
else data+=dis[j][i];
if (ans==-1 || data<ans) ans=data;
A: ;
}
printf("%d\n",ans);
return 0;
}