2022/12/30总结

验证栈序列

题目描述

给出两个序列 pushed 和 poped 两个序列,其取值从 1 到 n(n\le100000)n(n≤100000)。已知入栈序列是 pushed,如果出栈序列有可能是 poped,则输出 Yes,否则输出 No。为了防止骗分,每个测试点有多组数据。

输入格式

第一行一个整数 qq,询问次数。

接下来 qq 个询问,对于每个询问:

第一行一个整数 nn 表示序列长度;

第二行 nn 个整数表示入栈序列;

第三行 nn 个整数表示出栈序列;

输出格式

对于每个询问输出答案。

输入输出样例

输入 #1复制

2

5

1 2 3 4 5

5 4 3 2 1

4

1 2 3 4

2 4 1 3

输出 #1复制

Yes

No

  1. 这是一道关于数据结构”栈“的题目。我们需要在题目中模拟出出栈入栈的情况。

  1. 先在空栈中放入数组a的第一个元素。

  1. 在while循环中用栈顶元素的值不断与b数组的值相比较,如果不相等就继续往栈里面放值。如果退出while循环时栈顶的值等于b数组的值则进行出栈操作,然后b数组继续往下走进行下一次比较。如果退出while循环时栈顶元素的值不等于b数组当前元素的值说明出栈的顺序已经和b数组的顺序对不上了,直接退出for循环,输出”No“。

  1. for循环结束后,如果栈空则代表顺序对上了。

#include"stdio.h"
main()
{
    int q,n;
    scanf("%d",&q);
    while(q--)
    {
        int a[100010],b[100010];
        int i,j,m=0,top=0,data[100010]={0};
        scanf("%d",&n);
        for(i=0;i<n;i++)
            scanf("%d",&a[i]);
        for(i=0;i<n;i++)
            scanf("%d",&b[i]);
        data[top]=a[m++];
        for(i=0;i<n;i++)
        {
            while(m<n&&data[top]!=b[i])
            {
                top++;
                data[top]=a[m++];
            }    
            if(data[top]==b[i])
            top--;
            else
            {
                printf("No\n");
                break;
             }     
        }
        if(top==-1) printf("Yes\n");
    }
}

马的遍历

题目描述
有一个 n \times m n× m 的棋盘,在某个点 (x, y)( x, y) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。
输入格式
输入只有一行四个整数,分别为 n, m, x, y n, m, x, y
输出格式
一个 n \times m n× m 的矩阵,代表马到达某个点最少要走几步(不能到达则输出 -1−1)。
输入输出样例
输入 #1复制
3 3 1 1
输出 #1复制
0 3 2 3 -1 1 2 1 4
说明/提示
数据规模与约定
对于全部的测试点,保证 1 \leq x \leq n \leq 4001≤ xn≤400,1 \leq y \leq m \leq 4001≤ ym≤400。
  1. 本题使用bfs算法,和寻找迷宫出口的最短路径很相似。

  1. 同样的用一个二维数组记录下立足于当前位置可走的八个方向的偏差值。

  1. 首先要将起始值入队,但是它不算一步。

  1. 要记录下每一步的步数值,在上一步的基础上加一。

  1. 当队列为空时退出循环,输出棋盘。

#include"stdio.h"
struct zb
{
    int x;
    int y;
    int step;
}; 
main()
{
    struct zb que[40000];
    int i,j,n,m,x,y,k,nx,ny;
    int a[410][410],b[410][410]={0};
    int head,tail;
    int next[8][2]={{-1,2},{1,2},{2,1},
    {2,-1},{1,-2},{-1,-2},{-2,-1},{-2,1}};
    scanf("%d %d %d %d",&n,&m,&x,&y);
    for(i=1;i<=n;i++)
    {
    for(j=1;j<=m;j++)
    a[i][j]=-1;
    }
    head=1;
    tail=1;
    que[tail].x=x;
    que[tail].y=y;
    que[tail].step=0;
    tail++;
    a[x][y]=0;
    b[x][y]=1;
    while(head<tail)
    {
        for(k=0;k<8;k++)
        {
            nx=que[head].x+next[k][0];
            ny=que[head].y+next[k][1];
            if(nx<1||ny<1||nx>n||ny>m) continue;
            if(a[nx][ny]==-1&&b[nx][ny]==0)
            {
                b[nx][ny]=1;
                que[tail].x=nx;
                que[tail].y=ny;
                que[tail].step=que[head].step+1; 
                a[nx][ny]=que[tail].step;
                tail++;
            }    
        }
        head++;
    }
    for(i=1;i<=n;i++)
    {
    for(j=1;j<=m;j++)
    printf("%-5d",a[i][j]);
    printf("\n");
    }
}

素数环

题目描述
输入正整数n,把整数1,2,3,.....n组成一个环,使得相邻两个整数之和均为素数。输出时从整数1开始逆时针排列。同一个环应恰好只输出一次。n<=16
输入
输入一个正整数n(n<=16)

输出
分别输出每种满足条件的序列
样例输入 复制
6
样例输出 复制
1 4 3 2 5 6
1 6 5 2 3 4
  1. dfs问题。

  1. 第一步直接在数组里存入1,然后再走下一步。

  1. 判断当前的数加上上一步选出来的数判断它们的和是否为素数并且这个数在前面还没有被选用的话就存入数组a,然后进行下一步的选数,选完后记得将b数组打的标记取消,方便回溯。

  1. 输出时判断数组最后一个数加上第一个数是否为素数,是的话直接输出数组a,不是则不输出。

#include"stdio.h"
#include"math.h"
int n,a[20],b[20];
int prim(int n)
{
    int i;
    for(i=2;i<=sqrt(n);i++)
    if(n%i==0) return 0;
    return 1;
}
void fun(int step)
{
    int i,j;
    if(step==1) 
    {
        a[step]=1;
        b[1]=1;
        fun(step+1);
    }
    if(step==n+1&&prim(a[n]+a[1]))
    {        
        for(i=1;i<=n;i++)
        printf("%d ",a[i]);
        printf("\n");
        return ;
    }
    for(j=2;j<=n;j++)
    {
        if(prim(a[step-1]+j)&&b[j]==0)
        {
        a[step]=j;
        b[j]=1;
        fun(step+1);
        b[j]=0;
        }    
    }    
}
main()
{
    scanf("%d",&n);
    fun(1);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值