1.17总结

1.上午三个四十分钟

完成了第一次测试补题第三题和vj栈、队列、搜索题组的A题

Correct solution?

CF12B Correct Solution? - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

思路

将给定的数用认定为字符串,用字符串存起来,然后给给定的这个数的每一位数排序,如果这个数中没有0,就直接按排完序后顺序与“最小数”一一对比,如果每一位都相等,就证明“最小数”就是正确的最小数;如果有0的话,就用一个计数器得到0的个数,然后与所有0后面不为0的数调换,然后再与“最小数”的每一位进行比较,如果相同的话,就证明“最小数”就是正确的最小数。

昨天没有做出来的原因

将所有0后面的第一位不为0的数与第一位数调换出了错误。

代码实现

#include<stdio.h>
#include<string.h>
int main()
{
    char s1[10000],s2[10000],t;//两个字符数组存放给定的数和“最小数”
    gets(s1);
    gets(s2);
    int len1=strlen(s1);
    int len2=strlen(s2);
    int count=0,i,j,ans=0;
    if(len1==len2)//只有在两个字符串的长度相等时真实的最小值和“最小值”才有可能相等
    {
        for(i=0; i<len1; i++)
        {
            for(j=i+1; j<len1; j++)
            {
                if(s1[i]>s1[j])//从小到大排序
                {
                    t=s1[i];
                    s1[i]=s1[j];
                    s1[j]=t;
                }
            }
        }
        for(i=0; i<len1; i++)//记录0的个数,如果ans大于0就要进行交换,因为排序后的最小数不含前导0
        {
            if(s1[i]=='0')
                ans++;
        }
        if(ans==0)//如果字符串中没有0,那就真的最小数和“最小数”就每一位数进行比较
        {
            for(i=0; i<len1; i++)//如果每一位都相等就证明“最小数”就是实际的最小数
            {
                if(s1[i]==s2[i])
                    count++;
            }
        }
        else//如果字符串中有0,
        {
            for(i=0;i<len1;i++)
            {
                /*if(i<ans)//将为0的数全部移到它们后面第一个不为0的数的后面//这一段移动有错误。。。
                    s1[i]=s1[i+1];
                else if(i==ans)//全部为0的数的后面第一位不为0的数移到第一位a[0]
                    s1[i]=s1[0];
                else//其他的就不动
                    s1[i]=s1[i];*/
                if(i==ans)//把前面全部为0的后面一位数和第一位进行交换
                {
                    t=s1[0];
                    s1[0]=s1[ans];
                    s1[ans]=t;
                }
            }
            for(i=0;i<len1;i++)//然后就和字符串里面没有0的那种情况一样去进行比较
            {
                if(s1[i]==s2[i])
                count++;
            }
        }
    }
    if(len1!=len2||count!=len1)
        printf("WRONG_ANSWER");
    if(count==len1)
        printf("OK");
    return 0;
}

A-A

题目描述

现在有n个元素分别是1,2,3,...,n,我们想知道通过一个栈,在n次push/pop后,出栈序列可能是什么样的。例如n是5,那么入栈次序就是1,2,3,4,5,如果我们希望出栈次序同样是1,2,3,4,5,那只要每push一个数,就立即pop一个数。如果我们希望出栈次序是3,2,4,5,1,那么我们先让1,2,3入栈,然后pop出来3和2,接着4入栈后马上pop,再就是5入栈后马上pop,最后再把栈里的1pop出。再例如,如果我们希望出栈次序是5,4,1,2,3,这是办不到的,如果要让5最先出栈,那么出栈次序只可能是5,4,3,2,1
输入格式

输入由多块输入构成,每块的第一行是n,(1≤n≤1000),接着是多组测试数据,每组一行,每行由n个1到n的整数组成,直到某一行第一个数是0表示此输入块结束,然后是下一块数据。

当某一块的第一行的n是0的时候结束所有输入

输出格式

对每组数据,只要输出Yes或No,Yes表示能产生那样的出栈序列,No表示不能。 输入块与输入块之间要多输出一个空行分隔。注意对于最后一个n为0的输入块不要多输出空行。

样例输入

5
1 2 3 4 5
5 4 1 2 3
0
6
6 5 4 3 2 1
0
0

样例输出

Yes
No

Yes

思路

先输入n,然后1到n一次入栈,输入的序列从头开始与栈顶元素相比较,如果可以,就出栈,接着往下,如果对不上,就证明那个序列是不可能输出的。

代码实现

#include<stdio.h>
int a[1100],b[1100],top, i, n, p;
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0)
            break;
        while(scanf("%d",&a[0])!=EOF)
        {
            if(a[0]==0)
            {
                printf("\n");
                break;
            }
            for(i=1; i<n; i++)
                scanf("%d",&a[i]);
            top=-1;//此时栈为空
            p=n;//p用来表示此时应该是几出栈
            for(i=n-1; i>=0; i--)
            {
                top++;
                b[top]=a[i];//压栈
                while(1)
                {
                    if(top==-1||p!=b[top])
                        break;//如果此时栈为空或者不符合出栈条件,停止出栈
                    else
                    {
                        top--;//否则出栈
                        p--;
                    }
                }
            }
            if(top==-1)
                printf("Yes\n");
            else
                printf("No\n");
        }
    }
    return 0;
}

2.下午和晚上4个小时半

解决了栈、队列、搜索题组的B题和C题,F题做错了,输出样例没错,等会再仔细查查。

B-B

题目描述

定义一个二维数组:

int maze[5][5] = {

	0, 1, 0, 0, 0,

	0, 1, 0, 1, 0,

	0, 0, 0, 0, 0,

	0, 1, 1, 1, 0,

	0, 0, 0, 1, 0,

};


它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。

输入格式

一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。

输出格式

左上角到右下角的最短路径,格式如样例所示。  有坑有坑,输出的时候是数字加英文的逗号加空格再是数字。

输入样例

0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

输出样例

(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)

思路

这里简单说一下,我已经在代码中进行了详细的注释。遍历获得路径的最小步数,如果比前一天路径的最小的步数小就更新路径和最小步数。

代码实现

#include<iostream>
using namespace std;
int a[1100][1100];//0表示通路,1表示墙壁
int vis[1100][1100];//0表示未访问,1表示已访问
int d[4][2]= {{0,1},{1,0},{0,-1},{-1,0}};//发散的方向
int minstep=999999;//给最小值定一个较大的值,以获得第一次走的步数,方便后面进行比较
typedef struct node
{
    int xx;
    int yy;
} Node;//存路径
Node path[1100];
Node minpath[1100];
void dfs(int x,int y,int step)
{
    if(x==4&&y==4)//如果到达右下角就右生成一条新路径
    {
        if(minstep>step)//如果新路径的步数小于前一条的步数,就更新最小步数和路径
        {
            minstep=step;
            for(int i=0; i<step; i++)
            {
                minpath[i]=path[i];
            }
        }
        return;
    }
    for(int i=0;i<4;i++)//向四周运动
    {
        int dx=x+d[i][0];
        int dy=y+d[i][1];
        if(dx<0||dy<0||dx>4||dy>4)//不满足条件的
            continue;
        if(a[dx][dy]==0&&vis[dx][dy]==0)
        {
            vis[dx][dy]=1;//标记为已访问
            path[step].xx=dx;//记录路径
            path[step].yy=dy;
            dfs(dx,dy,step+1);//递归
            vis[dx][dy]=0;//回溯
        }
    }
    return;
}
int main()
{
    for(int i=0;i<5;i++)
    {
        for(int j=0;j<5;j++)
        {
            scanf("%d",&a[i][j]);
        }
    }
    vis[0][0]=1;//标记起点
    path[0].xx=0;//记录路径的起点
    path[0].yy=0;
    dfs(0,0,1);
    for(int i=0;i<minstep;i++)
    {
        printf("(%d, %d)\n",minpath[i].xx,minpath[i].yy);
    }
    return 0;
}

C-C

题目描述

You are given a string consisting of parentheses ( ) and [ ]. A string of this type is said to be correct:

  • if it is the empty string
  • if A and B are correct, AB is correct,
  • if A is correct, (A) and [A] is correct.

Write a program that takes a sequence of strings of this type and check their correctness. Your program can assume that the maximum string length is 128.

Input

The first line contains the number of test cases n. Each of the next n lines contains the string of parentheses ( ) and [ ].

Output

For each test case print in a separate line "Yes" if the expression is correct or "No" otherwise.

输入格式

The first line contains the number of test cases n. Each of the next n lines contains the string of parentheses ( ) and [ ].

输出格式

For each test case print in a separate line "Yes" if the expression is correct or "No" otherwise.

样例输入1

3
([])
(([()])))
([()[]()])()

样例输出1

Yes
No
Yes

样例输入2

22
((()

())))
([)]

((([[[]]])])
([])
(([()])))
([()[]()])()
[(])
(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
(])
[)]
[)))]
[[)]
([])
(([()])))
([()[]()])()
([)]
(
()(
[()

样例输出2

No
Yes
No
No
Yes
No
Yes
No
Yes
No
Yes
No
No
No
No
Yes
No
Yes
No
No
No
No

思路

用字符数组存括号,然后从头遍历数组,如果是左半边括号的话,就入栈,如果是有半边括号的话,就拿栈来,如果栈是空的或者是另一种的括号的右半边就直接输出No,然后跳出这一次的判断,到下一行括号去判断,可是如果对应的右半边括号的话,就把这个右半边括号出栈,但最后如果栈不是空的话,就证明匹配不成功。

代码实现

#include<stdio.h>
#include<string.h>
int main()
{
    int n;
    scanf("%d",&n);
    getchar();
    for(int j=0;j<n;j++)//多组输入
    {
        int top=0,sign=1;
        char a[130],v[130]={0};
        gets(a);
        int len=strlen(a);
        if(len==0)
        {
            printf("Yes\n");
            continue;
        }
        for(int i=0; i<len; i++)
        {
            if(a[i]=='('||a[i]=='[')//如果是左括号就入栈
            {
                v[++top]=a[i];
            }
            else//如果是右括号,就找离它最近的右括号,也就是让栈顶元素出来
            {
                if(a[i]==')')
                {
                    if(v[top]=='\0'||v[top]=='[')//如果这个时候栈是空的或者离这个右括号最近的栈顶元素是另一种括号,就直接输出No
                    {
                        sign=0;
                        break;
                    }
                    else//否则就出栈
                        top--;
                }
                if(a[i]==']')//同上
                {
                    if(v[top]=='\0'||v[top]=='(')
                    {
                        sign=0;
                        break;
                    }
                    else
                        top--;
                }
            }
        }
        if(v[top]!='\0'||sign==0)//最后如果栈不是空的,就证明匹配不成功
            printf("No\n");
        else
            printf("Yes\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值