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