题目大意:
给定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;*/ }