SRM 620

来源:互联网 发布:数控车床编程90例图 编辑:程序博客网 时间:2024/06/14 06:48

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";elsereturn "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;}




0 0