• The 2020 ICPC Asia Taipei-Hsinchu Site Programming Contest-C题 Pyramid (思维,递推,规律)


    The 2020 ICPC Asia Taipei-Hsinchu Site Programming Contest-C题 Pyramid (思维,递推,规律)

    题意:

    一个n*n的矩阵,取其上三角矩阵,每个点的初值为L,左上角为起点,每次在起点放入一个球,如果当前点为L,则向下走,若为R,则向右走,则之后L会变成R,或R变成L。
    问第k个球最后落入哪里。

    思路:

    解题关键:

    对于一个开关,若有x个小球经过此处,显然它会把 (lceilfrac{x}{2} ceil)个小球向左传送,会把(lfloorfrac{x}{2} floor)个小球向右传送。

    由此我们可以自顶向下推出每一层的每个开关处有多少小球经过。

    每一个开关会由其上方的1~2个开关转移过来,所以我们只需要开(dp[2][n])进行奇偶滚动数组dp求解。

    如果我们知道了在一个小球到达某开关之前此处有多少小球经过,之前有奇数次经过该开关那么本次就向右走,之前有偶数次经过该开关那么本次就向左走,由此就能得到小球在这个开关的走向。

    我们先求出前k-1个小球走过后每一个开关被走的次数,之后就能方便的求出第k个小球在每一层的走向,进而得到最后的结果。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    inline int readint() {int tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') { fh = -1; } c = getchar();} while (c >= '0' && c <= '9') { tmp = tmp * 10 + c - 48, c = getchar(); } return tmp * fh;}
    
    int n;
    int val[2][10010];
    
    int main()
    {
        int t;
        t = readint();
        while (t--) {
            n = readint();
            int k = readint();
            if(n==1)
            {
                printf("0
    ");
                continue;
            }
            val[0][0]=k-1;
            int ans=0;
            if(val[0][0]&1)
                ans++;
            for(int i=1;i<n-1;++i)
            {
                int last=0;
                for(int j=0;j<i;++j)
                {
                    val[i%2][j]=last+(val[(i-1)%2][j]+1)/2;
                    last=val[(i-1)%2][j]/2;
                }
                val[i%2][i]=last;
                if(val[i%2][ans]&1)
                {
                    ans++;
                }
            }
            printf("%d
    ",ans);
    
        }
        return 0;
    }
    
    
  • 相关阅读:
    并查集
    强联通分量,缩点
    最短路径
    最小生成树
    拓扑排序
    图的遍历
    图论基础知识
    数据库四种隔离级别
    MySQL 索引 乐观锁 悲观锁
    MYSQL+正则
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/14181051.html
Copyright © 2020-2023  润新知