• 【2016常州一中夏令营Day4】


    小 W 走迷宫
    【问题描述】
    小 W 被小 M 困在了一个方格矩阵迷宫里,矩阵边界在无穷远处,我们做出如下的
    假设:
    a. 每走一步时,只能从当前方格移动一格,走到某个相邻的方格上;
    b. 走过的格子立即塌陷无法再走第二次;
    c. 只能向北、东、西三个方向走。
    小 W 走了没多久就累坏了,他很想知道如果允许在方格矩阵上走 N 步,共有多少种不同的方案。( 开始时小 W 就在方格矩阵上的任意位置, 2 种走法只要有一步不一样,即被认为是不同的方案)
    【输入格式】
    一行输入 N。
    【输出格式】
    一行输出方案个数。
    【输入输出样例】
    game.in
    2

    game.out
    7

    【数据规模】
    对于 30%的数据:N<=20
    对于 100%的数据:N<=100

     

    题解

    a[i]表示最后一步向左走到达第i个格,它上一格不能是从右边走得到,易得 a[i]=a[i-1]+c[i-1]
    b[i]表示最后一步向右走到达第i个格,它上一格不能是从左边走得到的,易得  b[i]=b[i-1]+c[i-1]
    c[i]表示最后一步先上走到达第i个格,易得 c[i]=a[i-1]+b[i-1]+c[i-1]

    f[i]=a[i]+b[i]+c[i] =2*a[i-1]+2*b[i-1]+3*c[i-1] =2*f[i-1]+f[i-2]

    所以 f[i]=2*f[i-1]+f[i-2] 套上高精度即可

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    int n;
    struct hh
    {
        int n,a[105];
    };
    hh a,b,ans;
    
    hh sum(hh a,hh b)
    {
        int i;
        hh c;
        c.n=max(a.n,b.n);
        memset(c.a,0,sizeof(c.a));
        for(i=1;i<=c.n;i++)
        {
            c.a[i]+=a.a[i]+b.a[i];
            if(c.a[i]>=10)
            {
                c.a[i+1]+=c.a[i]/10;
                c.a[i]=c.a[i]%10;
            }
        }
        while(c.a[c.n+1])
        {
            ++c.n;
            if(c.a[c.n]>9)
            {
                c.a[c.n+1]+=c.a[c.n]/10;
                c.a[c.n]=c.a[c.n]%10;
            }
        }
        return c;
    }
    hh mul(hh a,int k)
    {
        int i,j;
        hh c;
        c=a;
        for(i=1;i<=c.n;i++) c.a[i]*=k;
        for(i=1;i<=c.n;i++)
            if(c.a[i]>9)
            {
                c.a[i+1]+=c.a[i]/10;
                c.a[i]=c.a[i]%10;
            }
        while(c.a[c.n+1])
        {
            c.n++;
            if(c.a[c.n]>=10)
            {
                c.a[c.n+1]+=c.a[c.n]/10;
                c.a[c.n]=c.a[c.n]%10;
            }
        }
        return c;
    }
    
    int main()
    {
        int i,j;
        hh temp;
        freopen("game.in","r",stdin);
        freopen("game.out","w",stdout);
        scanf("%d",&n);
        a.n=b.n=1;a.a[1]=1;
        for(i=1;i<=n-1;i++)
        {
            b=sum(a,b);a=sum(a,b);
            temp=a;
            a=b;
            b=temp;
        }
        ans=sum(mul(a,3),mul(b,2));
        for(i=ans.n;i;i--)
            printf("%d",ans.a[i]);
        fclose(stdin);
        fclose(stdout);
        return 0;
    }

    小 W 砍大树
    【问题描述】

    小 W 走出了迷宫,发现小 M 正等着他出城约会。不妙的的是,一棵大树挡在他们面前。这是一棵奇怪的树(当然是计算机领域的树,而且不一定是二叉树),所有叶子节点都是 True 或者 False。对于从上往下奇数层的非叶子节点是 and,偶数层非叶子节点为 or。
    树上每个节点的值是所有孩子节点的值进行该节点的运算操作。砍树的方法就藏在树根的值里!小 W 需要计算机大神你的帮助!
    QQ截图20160820122343

    上天为了撮合小 W 和小 M,大树以简单的括号序列给出: 上图可以描述为((A(BC))(DE))
    【输入格式】
    数据包括若干组,每组数据包含一行一个字符串。输入()表示结束。
    【输出格式】
    每组数据输出一行,包含:数据编号,点,空格,true 或 false。
    【输入输出样例】
    form.in

    ((F(TF))(TF))
    (TFT)
    ((TFT)T)
    ()

    form.out
    1. false
    2. false
    3. true
    【数据规模】
    对于 10%的数据:每行只包含一对括号;
    对于 30%的数据:只有嵌套的括号,没有并列的括号

     

    题解

    用栈维护即可

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    int len,top,cnt,t;
    int s[50005];
    char str[50005];
    int main()
    {
        int i,now;
        freopen("form.in","r",stdin);
        freopen("form.out","w",stdout);
        while(true)
        {
            scanf("%s",str+1);
            len=strlen(str+1);
            if(len==2&&str[1]=='('&&str[2]==')') break;
            cnt=top=1;
            s[top]='(';
            for(i=2;i<=len;i++)
            {
                if(str[i]=='T'){s[++top]=1;continue;}
                if(str[i]=='F'){s[++top]=0;continue;}
                if(str[i]=='('){s[++top]=2;cnt++;continue;} 
                if(cnt&1) now=1;
                else now=0;
                while(s[top]==1||s[top]==0) 
                {
                    if(cnt&1) now=now&s[top];
                    else now=now|s[top];
                    top--;
                }
                s[top]=now;
                cnt--;
            } 
            t++;
            if(s[1]) printf("%d. true
    ",t);
            else printf("%d. false
    ",t);
        }
        return 0;
    }

    小 W 数线段
    【问题描述】

    小 W 和小 M 终于携手走到了城市门前,却发现门上刻了一个 N*M 的点阵,相邻两点距离
    为 1,点阵里任取两点可连成线段。门上标注了:我问你 T 次,每次给你一个 L,你要答出
    有多少对线段长度是 L。答都对了你才可以进门。
    【输入格式】
    第一行三个整数:N,M,T。
    第二行为 T 个整数,即每个 L。
    【输出格式】
    一行 T 个整数,表示 T 个询问的答案。
    只有整数间存在空格。
    【输入输出样例】
    dist1.in
    3 3 3
    1 2 3
    dist1.out
    12 6 9
    dist2.in                                                                                                                                                                                                     4 5 1
    5
    dist2.out                                                                                                                                                                                                    2
    【数据规模】 
    对于 20%的数据:N,M<=20,T<=10
    对于 40%的数据:N,M<=1000,T<=100
    对于 60%的数据:N,M<=100000
    对于 100%的数据:N,M<=1000000000,T<=1000,L<=2*MAX(N,M)

     

    题解

    本原勾股数公式

    x^2+y^2=r^2y^2=(r-x)(r+x)

    d=gcd(r-x,r+x)

    y^2=d^2*(r+x)/d*(r-x)/d

    设  A=(r+x)/d      B=(r-x)/d

    则  y^2=d^2*A*B

    A
ot=B  并且 gcd(A,B)=1  得A和B都是完全平方数

    A=a^2     B=b^2 

    A+B=2r/d  得 a^2+b^2=2r/d

    所以 d2r 的因数

    先枚举 d 再枚举 2r 即可

  • 相关阅读:
    Mysql优化之6年工作经验总结
    mysql_innodb存储引擎的优化
    十六、MySQL授权命令grant的使用方法
    十五、Mysql字符集的那些事
    十四、索引
    十三、视图
    十二、存储过程
    十一、触发器
    十、存储引擎
    九、备份与恢复
  • 原文地址:https://www.cnblogs.com/yljiang/p/5796966.html
Copyright © 2020-2023  润新知