您的位置:首页 > 其它

srm 534

2016-02-17 11:46 274 查看

250

Description

给你一个1*n的棋盘。两人轮流行动,每一个人能够把”o”向右移动到空格子。或者跨越连续两个”o”到空格子。

一个”o”到最右端的时候消失。问谁获胜。

Solution

一个比較有趣的题,我们考虑每一个”o”到最右端的距离。两种行动事实上都是改变距离的奇偶,所以事实上仅仅须要考虑终于状态和距离和的奇偶性就可以。

Code

#include <bits/stdc++.h>
using namespace std;
const int N = 20;
int d[(1 << N) + 10];
class EllysCheckers {
public:
string getWinner(string board) {
int n = board.size();
int t = 0;
for (int i = 0; i < n; ++i) {
if (board[i] == 'o')    t += n - i - 1;
}
return t & 1 ? "YES" : "NO";
}
};


500

Description:

求把一个n(n≤1018)n(n\le 10^{18})数分解成几个给定的数组中的几个数的乘积形式的方案数,要求从给定数组中选出的数要两两互质。

Solution

非常easy反应到,因为2×3×...×43>10182\times 3\times...\times 43>10^{18},所以事实上nn会被分解成不超过15个质数,且每一个质数相应的数组中的数仅仅有一个。就能够状压dp了。

也能够直接用map来dp,能够证明,状态数不会太多。

Code:

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define F first
#define S second
typedef long long LL;
typedef pair<int, int> pii;
int p[20];
const int N = 505;
LL a
;
vector<int> b;
map<LL, LL> dp;
map<LL, LL>:: iterator it;
class EllysNumbers {
public:
long long getSubsets(long long n, vector <string> special) {
string s = accumulate(special.begin(), special.end(), string());
istringstream ss(s);
int m = 0, x;
while (ss >> x) a[m++] = x;
for (int i = 0; i < m; ++i)
if (__gcd(a[i], n / a[i]) == 1) b.pb(a[i]);
dp
= 1;
for (int i = 0; i < b.size(); ++i)
for (it = dp.begin(); it != dp.end(); it++)
if (it -> F % b[i] == 0) {
dp[it -> F / b[i]] += it -> S;
}
return dp[1];
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: