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; }