CodeForces Round #142(229A) - Shifts

       二分确定每个位置要变成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;
}


你可能感兴趣的:(CodeForces Round #142(229A) - Shifts)