题目描述
守护着神秘宝藏One Piece的是一把非常神秘的密码锁,这个密码锁有n排滚轮,每个滚轮有m个格子,刻着0,1两种数字。作为一把神秘的密码锁,开锁的方式却非常的简单,只要向左或向右转动滚轮使某一列的数字全是1就可以了。(向左滚动:所有的数字向左移动一位,最左边的数字移动到最右边,如001100左滚动一次变为011000,向右滚动与向左滚动操作相同,只是方向相反),作为即将成为海贼王的你,一定会选择最帅气的开锁方式———既用最少的次数来打开守护着神秘宝藏One Piece的密码锁。那么,请问最帅气的开锁次数需要转动密码锁几次呢?
输入
有多组数据输入,每个数据第一行为两个整数n,m表示有n排密码锁,每个密码锁有m个格子,其中(1≤n≤100,1≤m≤104)。接下来的有n行输入,表示每排密码锁的初始状态。
输出
对每组数据输出两行,第一行输出“Case # :”表示当前是几号样例(从1开始编号),第二行,如果可以开锁就输出一个整数表示最少需要移动几次,否则输出“Give Me A BOOM please”。(均不用输出“”号)
样例输入
2 3 111 000 3 6 101010 000100 100000
样例输出
Case #1: Give Me A BOOM please Case #2: 3
提示
对第一个样例,不可能开锁。第二个样例,可以第2行向左滚动一次,第3行向右滚动2次,最少3次就可以解锁。
题解:枚举每一列,再看每一行到达这一列的最近的1的距离,不存在就输出NO,再比较每一列的最小值即可。不过我这题不知道为什么总是AC不了,不能理解,能不能找出错误来???反正我是无语了。。。
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
char s[110][10010];
int main()
{
int t=0,n,m,i,j;
while (~scanf("%d%d",&n,&m))
{
getchar();
printf("Case #%d:\n",++t);
for (i=0;i<n;i++)
gets(s[i]);
int max=0x6fffffff;
int ff=1;
for (i=0;i<m;i++)
{
int k=0;
for (j=0;j<n;j++)
{
int f=1,l,r,a=0;
while (a<=(m/2+1))
{
l=i-a;
r=i+a;
if (l<0) l=m+l;
if (r>=m) r=r-m;
if (s[j][l]=='1' || s[j][r]=='1')
{
f=0;
break;
}
a++;
}
if (f==0) k+=a;
else
{
ff=0;
break;
}
}
if (ff)
if (max>k) max=k;
else break;
}
if (ff) printf("%d\n",max);
else printf("Give Me A BOOM please\n");
}
return 0;
}