A.牛牛扔牌(双端队列)
题目链接:https://ac.nowcoder.com/acm/contest/6219/A
分析:支持从牌顶拿出和牌底拿出,可以想到一个数据结构(双端队列),于是我们可以用STL的deque,或者自己写一个。
class Solution {
public:
/**
*
* @param x string字符串 字符串从前到后分别是从上到下排列的n张扑克牌
* @return string字符串
*/
bool check(int x)
{
if (x < 2) return false;
for (int i = 2; i <= x / i; ++i)
{
if (x % i == 0) return false;
}
return true;
}
string Orderofpoker(string x) {
//string p;
deque d;
for (int i = 0; i < x.size(); i += 2)
{
string c;
c += x[i];
c += x[i + 1];
d.push_back(c);
}
string res;
int sz = d.size();
while (sz)
{
string c;
if (!check(sz))
{
c = d.back();
d.pop_back();
res += c;
}
else
{
c = d.front();
d.pop_front();
res += c;
}
--sz;
}
return res;
}
};
B.疯狂过山车
题目链接:https://ac.nowcoder.com/acm/contest/6219/B
分析:经典的DP,从起点和终点求最长上升子序列,然后枚举分界点。
const int N = 1000005;
int a[N], b[N];
class Solution {
public:
/**
*
* @param n int整型
* @param num int整型vector
* @return int整型
*/
int getMaxLength(int n, vector& num) {
for (int i = 0; i < num.size(); ++i)
{
a[i] = 1;
if ((i - 1) >= 0)
{
if (num[i] > num[i - 1])
a[i] = a[i - 1] + 1;
}
}
for (int i = num.size() - 1; i >= 0; --i)
{
b[i] = 1;
if ((i + 1) <= n - 1)
{
if (num[i] > num[i + 1])
b[i] = b[i + 1] + 1;
}
}
int res = 0;
//枚举分界点
for (int i = 0; i < n; ++i)
{
res = max(res, a[i] + b[i] - 1);
}
return res;
}
};
C.牛牛的棋盘
题目链接:https://ac.nowcoder.com/acm/contest/6219/C
分析:经典的容斥原理题目,容斥原理可以查一下学一下。我们用二进制枚举所有的情况,我们的总方案是\(C_{n * m}^{k}\),其中含有不合法的情况。即第一行、最后一行、第一列、最后一列的不摆放棋子的情况要排除,我们可以用容斥原理去排除哪些不需要,哪些重复减了的情况要加回来。
const int N = 2005;
const int mod = 1e9 + 7;
using LL = long long;
int fact[N], infact[N];
class Solution {
public:
/**
*
* @param n int整型
* @param m int整型
* @param k int整型
* @return int整型
*/
int qmi(int a, int k, int p) // 快速幂模板
{
int res = 1;
while (k)
{
if (k & 1) res = (LL)res * a % p;
a = (LL)a * a % p;
k >>= 1;
}
return res;
}
int C(int a, int b)
{
if(a < b) return 0;
return (LL)fact[a] * infact[a - b] % mod * infact[b] % mod;
}
void init()
{
fact[0] = infact[0] = 1;
for (int i = 1; i < N; i++)
{
fact[i] = (LL)fact[i - 1] * i % mod;
infact[i] = (LL)infact[i - 1] * qmi(i, mod - 2, mod) % mod;
}
}
int solve(int n, int m, int k) {
init();
if (k == 2) return 2;
if (k < 2) return 0;
int res = 0;
for (int i = 0; i < 16; ++i)
{
int r = n, c = m;
int cnt = 0;
if ((i >> 3) & 1) --r, ++cnt;
if ((i >> 2) & 1) --r, ++cnt;
if ((i >> 1) & 1) --c, ++cnt;
if ((i >> 0) & 1) --c, ++cnt;
if(cnt & 1)
res = ((LL)res - C(r * c, k) + mod) % mod;
else
res = ((LL)res + C(r * c, k)) % mod;
}
return res % mod;
}
};