http://codeforces.com/contest/229/problem/A

开始的时候有了思路,不会写了,捏麻麻的。。

求出从正方向和逆方向使得一个坐标为1的最小步数,然后统计每一列为1的步数,求出最小值就是了。

View Code
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
int dp[110][10010];
int p[110][10010];
char s[110][10010];
int sum[10010];
int main()
{
    int n,m;
    //freopen()
    scanf("%d%d",&n,&m);
    memset(dp,0,sizeof(dp));
    memset(sum,0,sizeof(sum));
    for(int i=1;i<=n;i++)
        scanf("%s",s[i]);
    for(int i=1;i<=n;i++)
        for(int j=0;j<m;j++)
            dp[i][j+1]=s[i][j]-'0';
    int k;
    for(int i=1;i<=n;i++)
    {
        k=m;
        while(!dp[i][k]&&k)k--;
        if(k==0)
        {
            cout<<"-1"<<endl;
            return 0;
        }
        if(dp[i][1])
            p[i][1]=0;
        else
            p[i][1]=m-k+1;
        for( k=2;k<=m;k++)
        {
            if(dp[i][k])
                p[i][k]=0;
            else
                p[i][k]=p[i][k-1]+1;
        }
        k=1;
        while(!dp[i][k]&&k<m)k++;
        if(dp[i][m])
            p[i][m]=0;
        else
            p[i][m]=min(p[i][m],k);
        for( k=m-1;k>=1;k--)
        {
            if(dp[i][k])
                p[i][k]=0;
            else
                p[i][k]=min(p[i][k],p[i][k+1]+1);
        }
        for( k=1;k<=m;k++)
            sum[k]+=p[i][k];
    }
    int ans=sum[1];
    for(k=2;k<=m;k++)
        ans=min(ans,sum[k]);
    cout<<ans<<endl;
    return 0;
}
posted on 2012-10-02 16:32  一把刷子  阅读(205)  评论(0编辑  收藏  举报