【codevs2292】图灵机游戏

垃圾题目,毁我青春!

题目描述 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python 是一种流行的编程语言,它可以用于构建各种类型的应用程序,包括图灵机图灵机是一种理论模型,用于描述计算和自动化。它由英国数学家艾伦·图灵提出,被认为是计算机科学的重要基础。 在 Python 中,你可以使用基本的编程概念和数据结构来模拟图灵机的行为。例如,你可以使用条件语句、循环和变量来控制图灵机的状态转移和符号操作。你可以通过定义状态集合、符号集合、转移函数和停机状态来实现图灵机的功能。 以下是一个简单的 Python 代码示例,模拟了一个简化的图灵机: ```python # 定义图灵机的状态集合 states = {'q0', 'q1'} # 定义图灵机的符号集合 symbols = {'0', '1'} # 定义转移函数 transitions = { ('q0', '0'): ('q1', '1', 'R'), ('q1', '1'): ('q0', '0', 'L'), ('q1', '0'): ('q1', '1', 'R') } # 定义初始状态和输入串 initial_state = 'q0' input_string = '000111' # 初始化图灵机 current_state = initial_state tape = list(input_string) head_position = 0 # 模拟图灵机运行 while current_state != 'q1': symbol = tape[head_position] if (current_state, symbol) not in transitions: raise Exception('No transition defined for current state and symbol') new_state, new_symbol, move = transitions[(current_state, symbol)] tape[head_position] = new_symbol if move == 'R': head_position += 1 elif move == 'L': head_position -= 1 current_state = new_state # 输出最终的结果 output_string = ''.join(tape) print('Output:', output_string) ``` 请注意,这只是一个简化的示例,实际的图灵机可能更加复杂。在实际应用中,你可能需要使用更高级的编程技术和库来处理更复杂的图灵机模型。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值