【codevs2292】图灵机游戏

来源:互联网 发布:bi数据 编辑:程序博客网 时间:2024/05/17 21:53

垃圾题目,毁我青春!

题目描述 Description

【Shadow 1】第二题
Shadow最近知道了图灵机是什么(Shadow:就是一行格子和一个机器头移来移去的呗!),于是他突发奇想,创造了一个新游戏——“图灵机游戏”(Shadow:好听吧?)。
游戏规则如下:
在一条长长的纸上有N个格子,每个格子上都有一个数,第i格的数记为Ai,机器头刚开始在第1格。这个游戏有两个操作:
1.如果现在在第i格,则可以移动机器头到第Ai格;
2.把某个Ai减少或增加1。
然而,fotile96看了之后却不以为然。“嗯,你挑战一下用最少次数使机器头到达第N格吧,这样好玩些……”
现在,Shadow已经快Crazy了。于是,Shadow把脸转向了你……

输入描述 Input Description

第1行,1个整数N;
第2行,N个整数Ai。

输出描述 Output Description

1行,1个整数,为最少的操作次数。

样例输入 Sample Input

5
3 4 2 5 3

样例输出 Sample Output

3

数据范围及提示 Data Size & Hint

对于30%的数据,1≤N≤10;
对于60%的数据,1≤N≤1000;
对于100%的数据,1≤N≤100000,1≤Ai≤N。

样例解释

1.先将第1格的值加1
2.跳到第4格
3.跳到第5格,结束游戏

垃圾题目垃圾题目垃圾垃圾真垃圾!!!!
这个题大家可以看出来是最短路吧……
关键是建图……
所以说怎么建呢?
我一开始的想法是相邻两个点可以建图。
于是代码

#include<iostream>#include<queue>#include<cstdio>#include<algorithm>using namespace std;struct Edge{    int ff,tt,next;}edge[300010];int tot,head[100010],dist[100010],n;void build(int ff,int tt){    edge[++tot].ff=ff;    edge[tot].tt=tt;    edge[tot].next=head[ff];    head[ff]=tot;}queue<int>q;bool vis[100010];void spfa(){    q.push(1);    vis[1]=1;    dist[1]=0;    while(!q.empty())    {        int x=q.front();        q.pop();        vis[x]=0;        for(int i=head[x];i;i=edge[i].next)        {            Edge e=edge[i];            if(dist[e.tt]>dist[x]+1)            {                dist[e.tt]=dist[x]+1;                if(!vis[e.tt])                {                    q.push(e.tt);                    vis[e.tt]=1;                }            }        }    }}int main(){    cin>>n;    for(int i=1;i<=n;i++)    {        if(i!=1)build(i,i-1);        if(i!=n)build(i,i+1);        dist[i]=0x7fffffff;    }    for(int i=1;i<=n;i++)    {        int a;        cin>>a;        build(i,a);    }    spfa();    cout<<dist[n];    return 0;}

交!不交就是怂!怂就是A不了!
然后……
这里写图片描述
嘿嘿嘿~

第二个想法,我要每个点两两间建一条双向边……带权值……
然后……好像要开100000*100000的数组? (╯‵□′)╯︵┻━┻
肯定不行啊啊啊啊啊啊啊啊啊啊啊啊啊

第三个想法……试着调整一下建边数量
建少一点似乎很有趣?
于是代码

#include<iostream>#include<queue>#include<cstdio>#include<algorithm>using namespace std;struct Edge{    int ff,tt,next,dd;}edge[1000010];int tot,head[100010],dist[100010],n;void build(int ff,int tt,int dd){    edge[++tot].ff=ff;    edge[tot].tt=tt;    edge[tot].dd=dd;    edge[tot].next=head[ff];    head[ff]=tot;}queue<int>q;bool vis[100010];void spfa(){    q.push(1);    vis[1]=1;    dist[1]=0;    while(!q.empty())    {        int x=q.front();        q.pop();        vis[x]=0;        for(int i=head[x];i;i=edge[i].next)        {            Edge e=edge[i];            if(dist[e.tt]>dist[x]+e.dd)            {                dist[e.tt]=dist[x]+e.dd;                if(!vis[e.tt])                {                    q.push(e.tt);                    vis[e.tt]=1;                }            }        }    }}int main(){    cin>>n;    for(int i=0;i<=n;i++)dist[i]=0x7fffffff;    for(int i=1;i<=n;i++)    {        int a;        cin>>a;        for(int j=a-4;j<=a+4;j++)        {            build(i,j,abs(j-a)+1);        }    }    spfa();    cout<<dist[n];    return 0;}

交!不交就是怂!怂就是A不了!
然后……
这里写图片描述
好吧……好歹分多了

于是加上点想法
我们是不是可以判断一下当前点到达终点的权值来做……
于是代码

#include<iostream>#include<queue>#include<cstdio>#include<algorithm>using namespace std;struct Edge{    int ff,tt,next,dd;}edge[1000010];int tot,head[100010],dist[100010],n;void build(int ff,int tt,int dd){    edge[++tot].ff=ff;    edge[tot].tt=tt;    edge[tot].dd=dd;    edge[tot].next=head[ff];    head[ff]=tot;}queue<int>q;bool vis[100010];void spfa(){    q.push(1);    vis[1]=1;    dist[1]=0;    while(!q.empty())    {        int x=q.front();        q.pop();        vis[x]=0;        for(int i=head[x];i;i=edge[i].next)        {            Edge e=edge[i];            if(dist[e.tt]>dist[x]+e.dd)            {                dist[e.tt]=dist[x]+e.dd;                if(!vis[e.tt])                {                    q.push(e.tt);                    vis[e.tt]=1;                }            }        }    }}int main(){    cin>>n;    for(int i=0;i<=n;i++)dist[i]=0x7fffffff;    for(int i=1;i<=n;i++)    {        int a;        cin>>a;        for(int j=a-4;j<=a+4;j++)        {            build(i,j,abs(j-a)+1);        }        build(i,n,abs(n-a)+1);    }    spfa();    cout<<dist[n];    return 0;}

再交!
这里写图片描述
垃圾题!
本题的难点在于如何建图,只要建出图来一切好说……
垃圾出题人!

0 0
原创粉丝点击