[USACO Feb07] 银色莲花池

本文解析了银色莲花池问题的算法实现,通过宽度优先搜索寻找牛贝茜从起点到终点所需的最少莲花数及跳跃步数,并计算可能的路径数目。

[USACO Feb07] 银色莲花池

时间限制:1 s 内存限制:64 MB
译 By CmYkRgB123
描述
Farmer John 建造了一个美丽的池塘,用于让他的牛们审美和锻炼。这个长方形的池子被分割成了 M 行和 N 列( 1 ≤ M ≤ 30 ; 1 ≤ N ≤ 30 ) 正方形格子的 。某些格子上有惊人的坚固的莲花,还有一些岩石,其余的只是美丽,纯净,湛蓝的水。
贝茜正在练习芭蕾舞,她从一个莲花跳跃到另一个莲花,当前位于一个莲花。她希望在莲花上一个一个的跳,目标是另一个给定莲花。她能跳既不入水,也不到一个岩石上。
令门外汉惊讶的是,贝茜的每次的跳跃像国际象棋中的骑士一样:横向移动1,纵向移动2,或纵向移动,横向移动2。贝茜有时可能会有多达8个选择的跳跃。
Farmer John 在观察贝茜的芭蕾舞联系,他意识到有时候贝茜有可能跳不到她想去的目的地,因为路上有些地方没有莲花。于是他想要添加几个莲花使贝茜能够完成任务。一贯节俭的Farmer John想添加最少数量的莲花。当然,莲花不能放在石头上。
请帮助Farmer John确定必须要添加的莲花的最少数量。在添加的莲花最少基础上,算出贝茜从起始点跳到目标点需要的最少的步数。最后,还要算出满足添加的莲花的最少数量时,跳跃最少步数的跳跃路径的条数。
输入
第 1 行: 两个整数 M , N
第 2..M + 1 行:第 i + 1 行,第 i + 1 行 有 N 个整数,表示该位置的状态: 0 为水; 1 为莲花; 2 为岩石; 3 为贝茜开始的位置; 4 为贝茜要去的目标位置.
输出
第 1 行: 一个整数: 需要添加的最少的莲花数. 如果无论如何贝茜也无法跳到,输出 -1.
第 2 行: 一个整数: 在添加的莲花最少基础上,贝茜从起始点跳到目标点需要的最少的步数。如果第1行输出-1,这行不输出。
第 3 行: 一个整数: 添加的莲花的最少数量时,跳跃步数为第2行输出的值的跳跃路径的条数 如果第1行输出-1,这行不输出。
样例输入
4 8
0 0 0 1 0 0 0 0
0 0 0 0 0 2 0 1
0 0 0 0 0 4 0 0
3 0 0 0 0 0 1 0
样例输出
2
6
2

输出说明
至少要添加2朵莲花,放在了’x’的位置。
0 0 0 1 0 0 0 0…0 0 0 1 0 0 0 0
0 x 0 0 0 2 0 1…0 0 0 0 0 2 0 1
0 0 0 0 x 4 0 0…0 0 x 0 x 4 0 0
3 0 0 0 0 0 1 0…3 0 0 0 0 0 1 0
贝茜至少要条6步,有以下两种方案
0 0 0 C 0 0 0 0…0 0 0 C 0 0 0 0
0 B 0 0 0 2 0 F…0 0 0 0 0 2 0 F
0 0 0 0 D G 0 0…0 0 B 0 D G 0 0
A 0 0 0 0 0 E 0…A 0 0 0 0 0 E 0

一道极品搜索题,以后对搜索生疏的时候可以拿来练手QAQ

/*
    Name: 银色莲花池 
    Date: 14/10/16 07:42
    Description: 
        前两问很好解决 一遍宽搜可以很好的解决问题
        但是关键在第三问 要求输出方案(记住这一个教训方案数很可能需要开longlong甚至是写高精度)
        开始时想的是一遍宽搜跑出答案但这显然不现实 因为vis数组会很好的帮你去重
        于是又想到了用一个f[x][y][step][ned]表示在一个点用step步 添加ned荷叶的方案数虽然这可以很好的
        计算所有情况,但是也很好的超过了内存限制,迫不得已看了一下题解 -_-|||
        由于是最短距离到达终点 所以我们可以用 dis[x][y][ned] 表示用ned荷叶到达(x,y) 所用的最短距离
        way[x][y][ned] 表示方案数 于是乎得出了答案 
*/
#include <queue> 
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 35
#define maxm maxn*maxn
#define LL long long
#define inf 0x7f7f7f7f
LL n,m,ans=inf,num=inf,cnt,a[maxn][maxn],startx,starty,endx,endy;
LL st[8][2]={{-2,1},{-1,2},{2,1},{1,2},{-2,-1},{-1,-2},{1,-2},{2,-1}};
struct Node{
    LL x,y,step,ned;
    Node(LL A,LL B,LL C,LL D){
        x=A,y=B,step=C,ned=D;
    }
};
queue<Node> q;
bool vis[maxn][maxn][maxm],Check;
LL dis[maxn][maxn][maxm],way[maxn][maxn][maxm];
void Bfs(){
    while( !q.empty() ){
        Node temp=q.front(); q.pop();
        if(temp.ned>num) continue;
        for(LL i=0;i<8;i++){
            LL xx=temp.x+st[i][0],yy=temp.y+st[i][1];
            if(xx<1||yy<1||xx>n||yy>m)continue;
            if(a[xx][yy]==2)continue;
            if(a[xx][yy]==4){
                Check=1;
                if(num>temp.ned){
                    num=temp.ned;
                    ans=temp.step+1;
                    continue;
                }
                if(num==temp.ned){
                    if(ans>temp.step+1){
                        ans=temp.step+1;
                        continue;
                    }
                }
            }
            if(a[xx][yy]==1 && !vis[xx][yy][temp.ned]){             
                q.push(Node(xx,yy,temp.step+1,temp.ned));
                vis[xx][yy][temp.ned]=1;
            }
            if(a[xx][yy]==0 && !vis[xx][yy][temp.ned+1] ){
                q.push(Node(xx,yy,temp.step+1,temp.ned+1));
                vis[xx][yy][temp.ned+1]=1;
            }
        }
    }
    if(!Check) {printf("-1\n-1\n-1\n"); exit(0);}
    while( !q.empty() )q.pop();
    for(LL i=1;i<=n;i++)for(LL j=1;j<=m;j++)for(LL k=0;k<=num;k++) dis[i][j][k]=inf;
    memset(dis[startx][starty],0,sizeof(dis[startx][starty]));
    memset(way,0,sizeof(way));  way[startx][starty][0]=1;
    q.push(Node(startx,starty,0,0));
    a[endx][endy]=1;
    while( !q.empty() ){
        Node temp=q.front();q.pop();
        for(LL i=0;i<8;i++){
            LL xx=temp.x+st[i][0],yy=temp.y+st[i][1];
            if(xx<1||yy<1||xx>n||yy>m)continue;
            if(a[xx][yy]==2)continue;
            if(a[xx][yy]==1){
                if(temp.step+1<=ans && temp.ned<=num){
                    if(temp.step+1<=dis[xx][yy][temp.ned]){
                        if(temp.step+1<dis[xx][yy][temp.ned]){
                            q.push(Node(xx,yy,temp.step+1,temp.ned));
                            way[xx][yy][temp.ned]=0;
                        }
                        way[xx][yy][temp.ned]+=way[temp.x][temp.y][temp.ned];
                        dis[xx][yy][temp.ned]=temp.step+1;
                    }
                }
            }
            if(a[xx][yy]==0){
                if(temp.ned+1<=num && temp.step+1<=ans){
                    if(temp.step+1<=dis[xx][yy][temp.ned+1]){
                        if(temp.step+1<dis[xx][yy][temp.ned+1]){
                            q.push(Node(xx,yy,temp.step+1,temp.ned+1));
                            way[xx][yy][temp.ned+1]=0;
                        }
                        way[xx][yy][temp.ned+1]+=way[temp.x][temp.y][temp.ned];
                        dis[xx][yy][temp.ned+1]=temp.step+1;        
                    }
                }
            }
        }
    }
}
int main(){
    freopen("silvlily.in","r",stdin); freopen("silvlily.out","w",stdout);
    scanf("%lld%lld",&n,&m);
    LL x,y;
    for(LL i=1;i<=n;i++){
        for(LL j=1;j<=m;j++){
            scanf("%lld",&a[i][j]);
            if(a[i][j]==3){
                q.push(Node(i,j,0,0));
                vis[i][j][0]=1; startx=i;starty=j;
            }
            if(a[i][j]==4){endx=i,endy=j;}
        }
    }
    Bfs();
    printf("%lld\n%lld\n%lld\n",num,ans,way[endx][endy][num]);
    getchar(); getchar();
    return 0;
}
源码来自:https://pan.quark.cn/s/41b9d28f0d6d 在信息技术领域中,jQuery作为一个广受欢迎的JavaScript框架,显著简化了诸多操作,包括对HTML文档的遍历、事件的管理、动画的设计以及Ajax通信等。 本篇文档将深入阐释如何运用jQuery达成一个图片自动播放的功能,这种效果常用于网站的轮播展示或幻灯片演示,有助于优化用户与页面的互动,使网页呈现更加动态的视觉体验。 为了有效实施这一功能,首先需掌握jQuery的核心操作。 通过$符号作为接口,jQuery能够迅速选取DOM组件,例如$("#id")用于选取具有特定ID的元素,而$(".class")则能选取所有应用了某类class的元素。 在选定元素之后,可以执行多种行为,诸如事件监听、样式的变更、内容的更新以及动画的制作等。 关于“一个基于jQuery的图片自动播放功能”,首要任务是准备一组图片素材,这些素材将被整合至一个容器元素之中。 例如,可以构建一个div元素,将其宽度设定为单张图片的尺寸,再借助CSS实现溢出内容的隐藏,从而构建出水平滚动的初始框架。 ```html<div id="slider"> <img src="image1.jpg" alt="Image 1"> <img src="image2.jpg" alt="Image 2"> <!-- 更多图片内容... --></div>```接着,需要编写jQuery脚本以实现图片的自动切换。 这通常涉及到定时器的运用,以设定周期性间隔自动更换当前显示的图片。 通过使用`.fadeOut()`和`.fadeIn()`方法,能够实现图片间的平滑过渡,增强视觉效果。 ```javascript$(document).re...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值