• 栈和队列速度赛


    1、括弧匹配检验(check)

      【问题描述】

       假设表达式中允许包含两种括号:圆括号和方括号,其嵌套的顺序随意,如([]())或[([][])等为匹配,[(]()或(()))均为错误匹配。

    现在的问题是,要求检验一个给定表达式中的括弧是否正确匹配?

    输入一个中人包含圆括号和方括号的字符串,判断字符串中的括号是否匹配,匹配就输出“OK”,不匹配就输出“Wrong”。输入一个字符串:[([][])],输出“OK”

    【输入格式】

    输入仅一行字符(字符个数小于255)

    【输出格式】

    匹配的就输出“OK”,不匹配的就输出“Wrong”

    【输入样例】

    [(])

    【输出样例】

    Wrong

    用栈,m1记录当前栈内(的数量,m2记录当前栈内[的数量。

    从左往右扫描,1、碰到(或[入栈,栈顶指针+1,m1或m2+1

                        2、碰到),如果m1==0,或者当前栈顶不是(,输出Wrong。否则,用这个)抵消栈顶的(,m1--,top--

                        3、碰到],同2

                       4、最后如果栈内还有元素,即top!=0,输出Wrong,否则,输出OK

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    string s;
    char stack[256];
    int top,m1,m2;
    int main()
    {
        freopen("check.in","r",stdin);
        freopen("check.out","w",stdout);
        cin>>s;
        int len=s.length();
        for(int i=0;i<len;i++)
        {
            if(s[i]=='(') 
            {
                m1++;
                stack[top++]=s[i];
            }
            if(s[i]=='[') 
            {
                m2++;
                stack[top++]=s[i];
            }
            else if(s[i]==')')
            {
                if(!m1) 
                {
                    cout<<"Wrong";
                    return 0;
                }
                else if(stack[top-1]!='(')
                 {
                     cout<<"Wrong";
                    return 0;
                 }
                else 
                {
                    top--;
                    m1--;
                }
            }
            else if(s[i]==']')
            {
                if(!m2) 
                {
                    cout<<"Wrong";
                    return 0;
                }
                else if(stack[top-1]!='[')
                 {
                     cout<<"Wrong";
                    return 0;
                 }
                else 
                {
                    top--;
                    m2--;
                }
            }
        }
        if(top||m1||m2) cout<<"Wrong";
        else cout<<"OK";
    }

    2、最短路问题

    【问题描述】

        平面上有n个点(n<=100),每个点的坐标均在-10000~10000之间。其中的一些点之间有连线。若有连线,则表示可从一个点到达另一个点,即两点间有通路,通路的距离为两点间的直线距离。现在的任务是找出从一点到另一点之间的最短路径。

    【输入格式】

    输入文件为short.in,共n+m+3行其中:

    第1行为整数n

    第2行到第n+1行(共n行),每行两个整数x,y描述了一个点的坐标

    第n+2行为一个整数m,表示输入法中连线的个数

    此后m行,每行描述一条连线,由两个整数i和j组成,表示第i个点和第j个点之间有连线

    最后一行:两个整数s和t,分别表示源点和目标点

    【输出格式】

    输出文件为short.out,仅一行,一个实数(保留两位小数),表示从s到t的最短路长度

    【输入样例】

    5

    0 0

    2 0

    2 2

    0 2

    3 1

    5

    1 2

    1 3

    1 4

    2 5

    3 5

    1 5

    【输出样例】

    3.41

    这个题放在这儿应该用SPFA才符合队列,但我用的floyed

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    int n,m;
    double x[101],y[101];
    double d[101][101];
    int s,t;
    double work(int a,int b)
    {
        return sqrt(pow(abs(x[a]-x[b]),2)+pow(abs(y[a]-y[b]),2));
    }
    int main()
    {
            freopen("short.in","r",stdin);
            freopen("short.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%lf%lf",&x[i],&y[i]);
        for(int i=1;i<=n;i++)
         for(int j=1;j<=n;j++)
          d[i][j]=1000000;
         for(int i=1;i<=n;i++) d[i][i]=0; 
        int xx,yy; 
        scanf("%d",&m); 
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&xx,&yy);
            d[xx][yy]=d[yy][xx]=work(xx,yy);
        }
        for(int k=1;k<=n;k++)
         for(int i=1;i<=n;i++)
          for(int j=1;j<=n;j++)
                   d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
        scanf("%d%d",&s,&t);
        printf("%.2lf",d[s][t]);
    }
  • 相关阅读:
    [bzoj 2460]线性基+贪心+证明过程
    [Wc2011] Xor
    [BZOJ2844]线性基+xor本质不同第K大
    洛谷3857 [TJOI2008]彩灯
    HDU3949 异或线性基
    hdu3062 party --2-sat
    KM算法详解+模板
    Hopcroft-Karp算法
    bzoj 1135: [POI2009]Lyz
    hall定理的证明
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/6195066.html
Copyright © 2020-2023  润新知