easy:
两个数要向上还原一步的话,肯定是大减小。然后两组数谁比较大,谁就向上还原一步。
medium:
我们试想最后一次排序是什么样,就是和最终序列大小关系必须满足,但是有些相等的我们并不能保证可以排成最后的样子。
那么倒数第二次排序呢?即最后一次排序的那些可以保证关系我们可以不用管,其他的关系必须满足。。。
这样我们就能一直划分成一段一段。。。最后每个数单独一段就是possible
因为我们不知道几次可以完成,我们迭代超过m次,再接着迭代肯定是无用的。
(讲不太清楚,我把代码贴上来,flag[i]表示i与i+1有没有被隔开
代码:
#include <vector> #include <list> #include <map> #include <set> #include <deque> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> #include <cstring> using namespace std; class CandidatesSelection { public: string possible(vector<string> , vector<int> ); }; bool flag[55]; string CandidatesSelection::possible(vector<string> score, vector<int> result) { int i, j, k, n, m; n = score.size(); m = score[0].size(); memset(flag, 0, sizeof(flag)); for (j = 0; j < m + 2; ++j) { for (k = 0; k < m; ++k) { bool f = true; for (i = 0; i < n - 1; ++i) { if (flag[i]) continue; if (score[result[i]][k] > score[result[i + 1]][k]) { f = false; break; } } if (f == false) continue; for (i = 0; i < n - 1; ++i) { if (flag[i]) continue; if (score[result[i]][k] < score[result[i + 1]][k]) { flag[i] = true; } } } } bool f = true; for (i = 0; i < n - 1; ++i) { if (flag[i]) continue; if (result[i] < result[i + 1]) { flag[i] = true; } if (flag[i] == false) f = false; } if (f) return "Possible"; else return "Impossible"; }
hard:
看到counting,我刚开始以为是dp。。。其实是个高斯消元。。。
首先对于每个素数,如果一个数它包含这个素数奇数次,那么这种数必须出现偶数次
这样可以对于每个素数列一个方程
然后对于每一行每一列,再列一个方程
然后解出这个方程的自由元个数,2^自由元个数 就是答案。
代码:
#include <vector> #include <list> #include <map> #include <set> #include <deque> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> #include <cstring> using namespace std; class PerfectSquare { public: int ways(vector<int> ); }; const int maxn = 10005; int a[maxn][450], y[maxn]; int Gauss(int x[maxn], int n, int m) { int i, j, k; int now; now = 0; for (i = 0; i < n; ++i) { for (j = now; j < m; ++j) { if (a[j][i] == 1) { if (j == now) break; for (k = 0; k <= n; ++k) a[now][k] ^= a[j][k]; break; } } if (j == m) continue; for (j = now + 1; j < m; ++j) { if (a[j][i] == 0) continue; for (k = 0; k <= n; ++k) a[j][k] ^= a[now][k]; } now++; } for (j = now; j < m; ++j) if (a[j][n] == 1) return -1; return n - now; } map<int, int> m; int ed; vector<int> v[100000]; int PerfectSquare::ways(vector<int> x) { int n, i, j, k, p; n = x.size(); m.clear(); ed = 1; for (i = 0; i < n; ++i) { int j = x[i]; for (k = 2; k * k <= j; ++k) { if (j % k == 0) { int cnt = 0; while (j % k == 0) { cnt++; j /= k; } if (cnt % 2) { p = m[k]; if (p == 0) { p = ed; m[k] = ed++; v[p].clear(); } v[p].push_back(i); } } } if (j != 1) { p = m[j]; if (p == 0) { p = ed; m[j] = ed++; v[p].clear(); } v[p].push_back(i); } } memset(a, 0, sizeof(a)); for (j = 1; j < ed; ++j) { for (k = 0; k < v[j].size(); ++k) { a[j - 1][v[j][k]] = 1; } a[j - 1][n] = 0; } int nn = sqrt((double) n); for (i = 0; i < nn; ++i) { for (j = 0; j < nn; ++j) { a[ed - 1][i * nn + j] = 1; } a[ed - 1][n] = 1; ed++; } for (j = 0; j < nn; ++j) { for (i = 0; i < nn; ++i) { a[ed - 1][i * nn + j] = 1; } a[ed - 1][n] = 1; ed++; } int ans = Gauss(y, n, ed - 1); if (ans < 0) return 0; int pmod = 1000000007; int aans = 1; for (i = 0; i < ans; ++i) aans = aans * 2 % pmod; return aans; }