Cipher Lock

来源:互联网 发布:java 平均分配算法 编辑:程序博客网 时间:2024/06/05 19:21

Cipher Lock

Accepted : 23Submit : 76Time Limit : 2500 MSMemory Limit : 65536 KB 

题目描述

守护着神秘宝藏One Piece的是一把非常神秘的密码锁,这个密码锁有n排滚轮,每个滚轮有m个格子,刻着0,1两种数字。作为一把神秘的密码锁,开锁的方式却非常的简单,只要向左或向右转动滚轮使某一列的数字全是1就可以了。(向左滚动:所有的数字向左移动一位,最左边的数字移动到最右边,如001100左滚动一次变为011000,向右滚动与向左滚动操作相同,只是方向相反),作为即将成为海贼王的你,一定会选择最帅气的开锁方式———既用最少的次数来打开守护着神秘宝藏One Piece的密码锁。那么,请问最帅气的开锁次数需要转动密码锁几次呢?

输入

有多组数据输入,每个数据第一行为两个整数n,m表示有n排密码锁,每个密码锁有m个格子,其中(1≤n≤100,1≤m≤10 4 )。接下来的有n行输入,表示每排密码锁的初始状态。

输出

对每组数据输出两行,第一行输出“Case # :”表示当前是几号样例(从1开始编号),第二行,如果可以开锁就输出一个整数表示最少需要移动几次,否则输出“Give Me A BOOM please”。(均不用输出“”号)

样例输入

2 31110003 6101010000100100000

样例输出

Case #1:Give Me A BOOM pleaseCase #2:3
预处理出所有位置到最近1的距离,然后枚举每一列
#include <iostream>#include <cstdio>#include <cstring>using namespace std;int n,m,g[110][33000],dis[110][33000];const int INF=0x3f3f3f3f;int main(){  ///freopen("input.txt","r",stdin);  ///freopen("output.txt","w",stdout);  int cas=1;while(scanf("%d%d",&n,&m)!=EOF){  memset(dis,63,sizeof(dis));  getchar();  int B1=m,B2=2*m,B3=3*m;  for(int i=0;i<n;i++)  {    bool flag=false;    for(int j=0;j<m;j++)    {      char c;      scanf("%c",&c);      g[i][j]=(c=='1')?1:0;      g[i][j+B1]=g[i][j+B2]=g[i][j];      if(g[i][j]==1) dis[i][j+B1]=0;    }    getchar();  }  ///left_distance  for(int i=0;i<n;i++)  {    bool flag=false;    int dist=0;    for(int k=B1-1;k>=0;k--)    {      dist++;      if(g[i][k]==1) {flag=true; break;}    }    if(flag==false) continue;    dis[i][B1]=min(dis[i][B1],dist);    for(int j=B1+1;j<B2;j++)    {      if(dis[i][j]==0) continue;      else dis[i][j]=dis[i][j-1]+1;    }  }  ///right_distance  for(int i=0;i<n;i++)  {    bool flag=false;    int dist=0;    for(int k=B2;k<B3;k++)    {      dist++;      if(g[i][k]==1) {flag=true; break;}    }    if(flag==false) continue;    dis[i][B2-1]=min(dis[i][B2-1],dist);    for(int j=B2-2;j>=B1;j--)    {      if(dis[i][j]==0) continue;      else dis[i][j]=min(dis[i][j],dis[i][j+1]+1);    }  }  int ans=INF;  for(int i=B1;i<B2;i++)  {    int temp=0;    bool flag=true;    for(int j=0;j<n;j++)    {      if(dis[j][i]==INF)      {        flag=false; break;      }      temp+=dis[j][i];    }    if(flag) ans=min(ans,temp);    else { ans=INF; break; }  }  printf("Case #%d:\n",cas++);  if(ans>=INF) puts("Give Me A BOOM please");  else printf("%d\n",ans);}  return 0;}

0 0
原创粉丝点击