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個小球經過此處,顯然它會把 \(\lceil\frac{x}{2}\rceil\)個小球向左傳送,會把\(\lfloor\frac{x}{2}\rfloor\)個小球向右傳送。

由此我們可以自頂向下推出每一層的每個開關處有多少小球經過。

每一個開關會由其上方的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\n");
            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\n",ans);

    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章