第八届湘潭大学程序设计比赛
Cipher Lock | ||
Accepted : 36 | Submit : 140 | |
Time Limit : 2500 MS | Memory Limit : 65536 KB |
题目描述
守护着神秘宝藏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
此题在当时都没顾得上看~~~~(>_<)~~~~ ,因为被前两题卡死了。一直很忙,现在终于有时间重新看一下题了,WA了一次,还是以1600MS的时间AC了。自认为代码很挫(时间没降下去,空间消耗也大),但菜鸟尽力了......写第一篇博文,就用它留个纪念。
#include <iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int s[101][11000];
int road1[101][11000];
int road2[101][11000];
int road[101][11000];
bool pp;
int n,m;
int dfs1(int x,int y) //向左搜
{
if(y<=0)y=m;
if(road1[x][y]>=0)return road1[x][y];
if(road[x][y]==0)return 0;
return road1[x][y]=dfs1(x,y-1)+1;
}
int dfs2(int x,int y) //向右搜
{
if(y>m)y=1;
if(road2[x][y]>=0)return road2[x][y];
if(road[x][y]==0)return 0;
return road2[x][y]=dfs2(x,y+1)+1;
}
void DFS(int x)
{
int i;
memset(road1,-1,sizeof(road1));
memset(road2,-1,sizeof(road2));
for(i=1;i<=m;i++)
{
if(road1[x][i]<0)road1[x][i]=dfs1(x,i);
if(road2[x][i]<0)road2[x][i]=dfs2(x,i);
}
for(i=1;i<=m;i++)
road[x][i]=min(road1[x][i],road2[x][i]); //取最小距离
}
void wcb()
{
int i,j,k=1e9,h;
for(i=1;i<=m;i++)
{
k=0;
for(j=1;j<=n;j++)
k+=road[j][i];
h=min(h,k);
}
printf("%d\n",h);
}
main()
{
int i,j,k=0;
while(scanf("%d%d",&n,&m)==2)
{
pp=true;
printf("Case #%d:\n",++k);
char c;
bool p;
getchar();
for(i=1;i<=n;i++){ p=false;
for(j=1;j<=m;j++)
{
c=getchar();
if(c=='1')p=true,s[i][j]=1,road[i][j]=0;
else s[i][j]=0,road[i][j]=-1;
}
getchar();
if(!p) pp=false;}
if(!pp){printf("Give Me A BOOM please\n");continue;}
for(i=1;i<=n;i++)
DFS(i);
wcb();
}
}
时间也许消耗在 向“左搜和向右搜之后再取小”的步骤上了,但一时也想不出什么好办法,就这样了,以后想到了再来总结。
路漫漫其修远兮~~不断总结才能不断进步。
Problem C | Cipher Lock |