1. 程式人生 > >HDU 6048 思維+找規律

HDU 6048 思維+找規律

題意:

題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=6048
給出一個n*m的方格,以及1到n*m-1的數字,一開始按照一定的規則選擇每個數,從上到下,從左到右填入方格中,最後留一個空格子。
選數的規則為,每次選擇剩餘數中,第1個,第p+1個,第p*2+1個…,選完一輪後,去除選擇的數,剩下的數繼續按照這個規則來選。
如果方格中的空格子可以通過和相鄰的數字交換位置來移動,問最後是否可以得到1到n*m-1這些數字按照從左到右從上到下的順序放在方格中(右下角是空格)。

思路:

首先,找規律或者一些手段發現其實只要將遊戲開始時方格中的數字從左到右從上到下排成一列,如果逆序對數是偶數就可行,否則不可行。
如何計算在那種規則下逆序對的數目,考驗思維了,注意到數列一開始就是遞增的,每一輪從中選擇一個數x,那麼剩下的數且位置在x之前的數有多少個,就會產生多少個逆序對。而每一輪選擇完成之後,可以發現數列仍然是遞增的,這樣每一輪的結果可以直接統計出來,然後看一共會完成多少輪,最後若剩餘的數不大於p了,那麼就不會產生逆序對。

程式碼:

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1005;

int a[MAXN * MAXN];

int main() {
    //freopen("in.txt", "r", stdin);
    int T;
    scanf("%d", &T);
    while (T--) {
        int n, m, p;
        scanf("%d%d%d", &n, &m, &p);
        int now = n * m - 1
, cnt = 0; while (now > p) { int tmp = (now - 1) / p + 1; cnt += (tmp - 1) * tmp / 2 * (p - 1); now -= tmp; } if (cnt & 1) puts("NO"); else puts("YES"); } return 0; }