usaco之lilypad 大合集!集合poj 3271 bzoj 1632

来源:互联网 发布:优酷ace mac 编辑:程序博客网 时间:2024/06/06 17:33

呜咕~~今天有考试了。
先来反思一下。
1.第一题,思路很简单的模拟。。但是由于 一开始智障存的int取代了本来该有的都double导致 调了很久。还是缺根弦。
2.很简单的判断寻找的点是否在路径上的方法没有想到。而且其实并没有很深刻的理解。。
3.暂时不知道

所以我们来说一下 题目这两道题:
第一道:
poj 3271 其实这个原来 写过题解了。。这会放一起再对比一遍。。
第二道:
bzoj 1632

题意:
第一道:
这里写图片描述
这里写图片描述

第二道:
Farmer John 建造了一个美丽的池塘,用于让他的牛们审美和锻炼。这个长方形的池子被分割成了 M 行和 N 列( 1 ≤ M ≤ 30 ; 1 ≤ N ≤ 30 ) 正方形格子的 。某些格子上有惊人的坚固的莲花,还有一些岩石,其余的只是美丽,纯净,湛蓝的水。 贝茜正在练习芭蕾舞,她从一个莲花跳跃到另一个莲花,当前位于一个莲花。她希望在莲花上一个一个的跳,目标是另一个给定莲花。她能跳既不入水,也不到一个岩石上。 令门外汉惊讶的是,贝茜的每次的跳跃像中国象棋的马一样:横向移动1,纵向移动2,或纵向移动1,横向移动2。贝茜有时可能会有多达8个选择的跳跃。 Farmer John 在观察贝茜的芭蕾舞联系,他意识到有时候贝茜有可能跳不到她想去的目的地,因为路上有些地方没有莲花。于是他想要添加几个莲花使贝茜能够完成任务。一贯节俭的Farmer John想添加最少数量的莲花。当然,莲花不能放在石头上。 请帮助Farmer John确定必须要添加的莲花的最少数量。在添加的莲花最少基础上,算出贝茜从起始点跳到目标点需要的最少的步数。最后,还要算出满足添加的莲花的最少数量时,跳跃最少步数的跳跃路径的条数。

所以 找不同?哪里不一样呢?

1.第一道有2问,第二道3问。【【这不废话吗哈哈】】
2.第一道问的方案数是荷叶摆放的方案数,注意是摆放方案数,第二道是跳跃路径的方案数并且还是在2个优先级条件的情况下。。

分析即题解:

是有差别的两种方案问法相对应的有不同解法。
一定要把握好这个才ok
这里写图片描述
就像此图 poj题的答案应该是1 因为只有一种摆放方式
但是bzoj呢就应该是 2种 因为在放的个数和路径长度都有限的情况 也是一样的

所以 针对第一道题。我们必须预先处理初第一种的连边情况 建图才ok

但是对于第二种 只用在spfa的松弛过程中智姐加判等于就ok

其实有个bug。。我一直以为不能两边spfa那么些我在想 怎么判断点在不在啊。。连dis[v]=dis[u]+1这种可以判的条件都忘了。

所以就解决了。相比之下第二个简单一些

代码:
第一道

#include<cstdio>#include<cstring>#include<queue>#include<vector>#include<algorithm>#define ll long longusing namespace std;//by mars_chint n,m;int map[35][35],vis[35][35],dis[1005],inq[1005],pre[1005],g[35][35];ll ans[1005];int sx,sy,ex,ey;int dx[8]={2,2,1,1,-1,-1,-2,-2};int dy[8]={1,-1,-2,2,2,-2,-1,1}; struct data{    int f,t,nxt;    int w;}e[100005];int first[1005],tot;struct node{    int f,t,nxt;    int w;}bian[100005];int head[1005],tol;void add(int a,int b,int c){    e[tot].f=a;    e[tot].t=b;    e[tot].w=c;    e[tot].nxt=first[a];    first[a]=tot++;}void bfs(int x,int y){    memset(g,0,sizeof(g));    queue<pair<int,int > > q;    q.push(make_pair(x,y));    g[x][y]=1;    while(!q.empty())    {        pair<int,int> P=q.front();        q.pop();        for(int i=0;i<8;i++)        {            int nx=P.first+dx[i],ny=P.second+dy[i];            if(nx<=0 || ny<=0 || ny>m || nx>n) continue;            if(g[nx][ny]) continue;            g[nx][ny]=1;            if(map[nx][ny] == 1) q.push(make_pair(nx,ny));            else             {                //printf("%d %d\n",(x-1)*m+y,(nx-1)*m+ny);                 add((x-1)*m+y,(nx-1)*m+ny,1);            }         }     }}void spfa(int src){    memset(dis,0x3f,sizeof(dis));    dis[src]=0;    queue<int> q;    q.push(src);    ans[src]=1LL;    while(!q.empty())    {        int u=q.front();        q.pop();        if(pre[u] == 2) continue;        for(int i=first[u];i!=-1;i=e[i].nxt)        {            int v=e[i].t;            //printf("%d %d\n",u,e[i].t);            if(dis[v]>dis[u]+e[i].w)            {                dis[v]=dis[u]+e[i].w;                ans[v]=ans[u];                q.push(v);             }            else if(dis[v] == dis[u]+e[i].w)            {                ans[v]+=ans[u];            }        //  printf("answer is %d\n",ans[v]);         }    }}int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)    {        for(int j=1;j<=m;j++)        {            scanf("%d",&map[i][j]);            pre[(i-1)*m+j]=map[i][j];            if(map[i][j] == 3) sx=i,sy=j;            if(map[i][j] == 4) ex=i,ey=j;        }    }     memset(first,-1,sizeof(first));    for(int i=1;i<=n;i++)    {        for(int j=1;j<=m;j++)        {            bfs(i,j);        }    }    bfs(sx,sy);//罪魁祸首 在这里。。。。。。。。。。把原点又走了一遍、、、qaq     spfa((sx-1)*m+sy);    int ed=(ex-1)*m+ey;    int res=dis[ed];    if(dis[ed] == 1061109567)    {        printf("-1\n");        return 0;    }    printf("%d\n",res-1);    printf("%lld\n",ans[ed]);    return 0;}

第二道暂时还没有 明天po 。。

来了~~

#include<cstdio>#include<algorithm>#include<cstring>#include<queue>using namespace std;//by mars_chint n,m;int sx,sy,ex,ey;int dx[8]={2,2,1,1,-1,-1,-2,-2};int dy[8]={1,-1,-2,2,2,-2,-1,1}; int map[105][105],vis[105][105],add[105][105],dis[105][105],inq[10005];long long ans[105][105];void bfs(){    memset(add,0x3f,sizeof(add));    memset(dis,0x3f,sizeof(dis));    add[sx][sy]=0,dis[sx][sy]=0;    vis[sx][sy]=1;    ans[sx][sy]=1;    queue<pair<int,int > > q;    q.push(make_pair(sx,sy));    while(!q.empty())    {        pair<int,int> P=q.front();        q.pop();        vis[P.first][P.second]=0;        for(int i=0;i<8;i++)        {            int nx=P.first+dx[i],ny=P.second+dy[i];            if(nx<1 || ny<1 || nx>n || ny>m) continue;            if(map[nx][ny] == 2) continue;            int cnt=0;            if(map[nx][ny]==0) cnt=1;            if(add[nx][ny]>add[P.first][P.second]+cnt)            {                add[nx][ny]=add[P.first][P.second]+cnt;                dis[nx][ny]=dis[P.first][P.second]+1;                ans[nx][ny]=ans[P.first][P.second];                if(!vis[nx][ny])                {                    vis[nx][ny]=1;                    q.push(make_pair(nx,ny));                }            }            else if(add[nx][ny]==add[P.first][P.second]+cnt)            {                if(dis[nx][ny]>dis[P.first][P.second]+1)                {                    dis[nx][ny]=dis[P.first][P.second]+1;                    ans[nx][ny]=ans[P.first][P.second];                    if(!vis[nx][ny])                    {                        vis[nx][ny]=1;                        q.push(make_pair(nx,ny));                    }                }                else if(dis[nx][ny] == dis[P.first][P.second]+1)                {                    ans[nx][ny]+=ans[P.first][P.second];                    if(!vis[nx][ny])                    {                        vis[nx][ny]=1;                        q.push(make_pair(nx,ny));                    }                }            }         }     }}int main(){    //freopen("lilypad.in","r",stdin);    //freopen("lilypad.out","w",stdout);    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)    {        for(int j=1;j<=m;j++)        {            scanf("%d",&map[i][j]);            if(map[i][j] == 3) sx=i,sy=j;            if(map[i][j] == 4) ex=i,ey=j;        }     }      bfs();     if(dis[ex][ey] == 1061109567)     {        printf("-1\n");        return 0;     }     else     {        printf("%d\n%d\n%lld\n",add[ex][ey],dis[ex][ey],ans[ex][ey]);     }}
0 0
原创粉丝点击