第八届湘潭大学程序设计比赛 c题

第八届湘潭大学程序设计比赛

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 CCipher Lock
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值