2017 Multi-University Training Contest - Team 2 Puzzle

题目大意:

给定n, m, p。然后按照一个规则往n*m的方格里填数,最后一个方格是空格,然后玩拼图游戏,问能否复原

规则是:把1~n*m-1的排列中的第1,p+1,2*p+1.....个数依次取出来,不能再取就重新执行这个操作。

 

题解:

http://bestcoder.hdu.edu.cn/blog/2017-multi-university-training-contest-2-solutions-by-%E7%94%B5%E5%AD%90%E7%A7%91%E6%8A%80%E5%A4%A7%E5%AD%A6/

这个题解给的很详细

需要注意的是,我这里加了一个剪枝才过的。。。

就是当每次只能取一个的时候,就直接跳出来。

后面注释掉的部分是打表找规律

#include <iostream>
#include <vector>
using namespace std;
int f[51], v[51];
vector<int> V;
int main()
{
    long long n, m, p, T;
    cin>>T;
    for(int ncase = 1; ncase <= T; ncase++){
        cin>>n>>m>>p;
        n = n*m-1;
        long long d = p-1, ans = 0;
        while(n > 0){
            long long m = (n-1)/p + 1;
            if(m == 1) break;
            ans += m*(m-1)*d/2;
            n -= m;
        }
        //cout<<ans<<endl;
        if(ans&1) cout<<"NO"<<endl;
        else cout<<"YES"<<endl;
    }
    /*int n = 50, p = 5;
    for(int i = 1; i <= n; i++){
        int j;
        for(j = 1; j <= n; j++) if(!f[j]){
            V.push_back(j);
            f[j] = 1;
            break;
        }
        if(j == n+1) break;
        int temp = p;
        while(j < n){
            j++;
            if(!f[j]) temp--;
            if(temp == 0) {
                V.push_back(j);
                f[j] = 1;
                temp = p;
            }
        }
    }
    for(int i = 0; i < n; i++){
        for(int j = i+1; j < n; j++)
            if(V[i] > V[j]) v[i]++;
    }
    for(int i = 0; i < n; i++)cout<<v[i]<<" "; cout<<endl;*/
}

 

posted @ 2017-07-28 09:02  Saurus  阅读(202)  评论(0编辑  收藏  举报