Cipher Lock

题目描述

守护着神秘宝藏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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值