为了督促自己补题!以后都开博客记录!
本次比赛:吉首大学第九届"新星杯"大学生程序设计大赛(重现赛)
时间:2020/1/5
共做出8题,最后卡在了一道博弈题。
A:比赛的时侯看了下题目,没看懂,然后跳了。其实也很简单,意思就是,如果这次找到了,那么下一次的起点就变成了这个点,下一次我们直接减去它就可以了。
/// .-~~~~~~~~~-._ _.-~~~~~~~~~-.
/// __.' ~. .~ `.__
/// .'// \./ \\`.
/// .'// | \\`.
/// .'// .-~"""""""~~~~-._ | _,-~~~~"""""""~-. \\`.
/// .'//.-" `-. | .-' "-.\\`.
/// .'//______.============-.. \ | / ..-============.______\\`.
/// .'______________________________\|/______________________________`.
#include
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const double pi = acos(-1);
namespace {
template inline void read(T &x) {
x = 0; T f = 1;char s = getchar();
for(; !isdigit(s); s = getchar()) if(s == '-') f = -1;
for(; isdigit(s); s = getchar()) x = (x << 3) + (x << 1) + (s ^ 48);
x *= f;
}
}
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define _for(n,m,i) for (register int i = (n); i < (m); ++i)
#define _rep(n,m,i) for (register int i = (n); i <= (m); ++i)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define lowbit(x) x & (-x)
#define pii pair
#define fi first
#define se second
set se[13];
int main() {
int x, y, z, q, a;
read(x); read(y); read(z);
se[0].insert(0);
for(int i = 1; i <= 12; i++) {
for(auto it : se[i-1]) {
se[i].insert(it + x);
se[i].insert(it - x);
se[i].insert(it + y);
se[i].insert(it - y);
se[i].insert(it + z);
se[i].insert(it - z);
}
}
int st = 0;
read(q);
while(q--) {
read(a);
a = a - st;
if(se[12].find(a) != se[12].end()) {
puts("YES");
st = abs(a);
}
else {
puts("NO");
st = 0;
}
}
}
B: 签到题,不谈。
C:写的时侯看错了题目, wa了几发才发现读错了题目。实际上只会移动一次。然后打标记在判断即可
D:二分答案即可
E:签到题
F:比赛的时侯没有看0.0,n很大,所有肯定有点规律,n > 178之后 模数就变成0了,发现这个就很简单了
/// .-~~~~~~~~~-._ _.-~~~~~~~~~-.
/// __.' ~. .~ `.__
/// .'// \./ \\`.
/// .'// | \\`.
/// .'// .-~"""""""~~~~-._ | _,-~~~~"""""""~-. \\`.
/// .'//.-" `-. | .-' "-.\\`.
/// .'//______.============-.. \ | / ..-============.______\\`.
/// .'______________________________\|/______________________________`.
#include
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const double pi = acos(-1);
namespace {
template <typename T> inline void read(T &x) {
x = 0; T f = 1;char s = getchar();
for(; !isdigit(s); s = getchar()) if(s == '-') f = -1;
for(; isdigit(s); s = getchar()) x = (x << 3) + (x << 1) + (s ^ 48);
x *= f;
}
}
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define _for(n,m,i) for (register int i = (n); i < (m); ++i)
#define _rep(n,m,i) for (register int i = (n); i <= (m); ++i)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define lowbit(x) x & (-x)
#define pii pair
#define fi first
#define se second
const LL Mod = 3777105087;
LL arr[200];
int main() {
LL n, x, y;
arr[1] = 1;
_rep(2, 178, i) arr[i] = (arr[i-1] * i) % Mod;
while(cin >> n >> x >> y) {
if(n >= 178) n = 178;
LL ret = 0;
_rep(2, n, i) {
ret = (ret + arr[i]) % Mod;
}
if(y) _rep(1, x, i) ret = ret * 2 % Mod;
ret = (ret + 1) % Mod;
cout << ret << "\n";
}
}
G: DP,是我做不出来的题。。在题解和AC代码的帮助下把这题补了;
一个显然的结论,一个数的位数大的一定大于位数小的。所以难求的就是等于的情况。dp[i][j][k],1 <= i <=n, 1 <= j <= m, 0 <= k <= 1;
k为0 时代表 一个串的第i个匹配到另一个串的第j个时,大于它的个数
k为1时代表 一个串的第i个匹配到另一个串的第j个时,等于它的个数
然后发现每一个状态都是从上一个状态转移过来的,所以空间是可以优化的,可以用滚动数组。然后再发现只能从上一个状态中长度较小的转移到较大的,所以实际上逆序一下就可以了;
转移方程:
dp[j][0] += dp[j-1][0] 大于的到这里还是大于
dp[j][1] += dp[j-1][1] s[i] == t[j]; 相等的到这里还是相等
dp[j][0] += dp[j-1][1] s[i] > t[j];现在相等的也变成大于的了
最后dp[m][0] 就是答案。但是这得m >= n 的时侯。因为我们少算了一部分,当n >= m 时,长度为 m + 1 到 n 的都是一定大于的,但是前面统计不到。所以还得DP一次长度为 i 的数字的个数,不能有前导0;
dp[i][j] 代表前i个中,长度为 j 的有多少个。
转移方程:
dp[i][j] += dp[i-1][j-1]
dp[i][1] += s[i] != ‘0’;
本着优化的精神 我们发现和上面一样的,逆序一下就可以变成一维。然后再把大于m + 1的部分加到答案中就可以。
#include
using namespace std;
namespace {
template <typename T> inline void read(T &x) {
x = 0; T f = 1;char s = getchar();
for(; !isdigit(s); s = getchar()) if(s == '-') f = -1;
for(; isdigit(s); s = getchar()) x = (x << 3) + (x << 1) + (s ^ 48);
x *= f;
}
}
#define _rep(n,m,i) for (register int i = (n); i <= (m); ++i)
const int N = 3e3+5;
const int Mod = 998244353;
int dp[N][2], dp1[N];
char s[N], t[N];
inline int min(int a, int b) {
return a < b ? a : b;
}
inline void Mov(int &a, int b) {
a += b;
if(a > Mod) a -= Mod;
}
int main() {
int k;
read(k);
while(k--) {
memset(dp, 0, sizeof dp);
memset(dp1, 0, sizeof dp1);
int n, m;
read(n); read(m);
scanf("%s %s", s + 1, t + 1);
dp[0][1] = 1;
_rep(1, n, i)
for(int j = min(i, m); j >= 1; --j) {
if(s[i] == t[j]) Mov(dp[j][1], dp[j-1][1]);
if(s[i] > t[j]) Mov(dp[j][0], dp[j-1][1]);
Mov(dp[j][0], dp[j-1][0]);
}
_rep(1, n, i) {
for(int j = i; j >= 1; --j) {
if(j == 1) dp1[1] += s[i] != '0';
else Mov(dp1[j], dp1[j-1]);
}
}
_rep(m+1, n, i) Mov(dp[m][0], dp1[i]);
printf("%d\n", dp[m][0]);
}
}
H:模拟即可
I:二进制中1的数量
J:思维题,找最长的连续递增子序列,n减之即可
K:并查集
L:
M:
刚开始写了下深搜,推了个假结论。还是以前没有搞清楚SG函数的作用。其实就是道SG函数的裸题。SG(n)为真即真。
/// .-~~~~~~~~~-._ _.-~~~~~~~~~-.
/// __.' ~. .~ `.__
/// .'// \./ \\`.
/// .'// | \\`.
/// .'// .-~"""""""~~~~-._ | _,-~~~~"""""""~-. \\`.
/// .'//.-" `-. | .-' "-.\\`.
/// .'//______.============-.. \ | / ..-============.______\\`.
/// .'______________________________\|/______________________________`.
#include
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const double pi = acos(-1);
namespace {
template <typename T> inline void read(T &x) {
x = 0; T f = 1;char s = getchar();
for(; !isdigit(s); s = getchar()) if(s == '-') f = -1;
for(; isdigit(s); s = getchar()) x = (x << 3) + (x << 1) + (s ^ 48);
x *= f;
}
}
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define _for(n,m,i) for (register int i = (n); i < (m); ++i)
#define _rep(n,m,i) for (register int i = (n); i <= (m); ++i)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define lowbit(x) x & (-x)
#define pii pair
#define fi first
#define se second
const int N = 1e3+5;
int Sg[N], vis[N], a[N];
int n, m;
bool SG(int n) {
for(int i = 1; i <= n; i++) {
memset(vis, 0, sizeof vis);
for(int j = 1; j <= m; j++) {
if(i - a[j] >= 0) vis[Sg[i - a[j]]] = 1;
}
for(int j = 0; j <= n; j++) {
if(!vis[j]) {
Sg[i] = j;break;
}
}
}
return Sg[n];
}
int main() {
read(n); read(m);
for(int i = 1; i <= m; i++) read(a[i]);
if(SG(n)) puts("Y");
else puts("N");
}