题目:B(规律)
题意:
给你长度为 k 的 a 序列,然后根据题目要求构造长度为 n 的 b 序列,求 b 序列中有多少个
\(b_i\)%m \(<=b_{i+1}\)%m (0 <= i < n)。
思路:
因为数据范围过大,很明显这题不能暴力求解。首先很明显我们可以将 a 序列全部 %m,这显然不会对答案造成影响,然后我们枚举样例就会发现每当 \(b_i+a_j\) > m 时,此时很明显\(b_{i-1} > b_i\)。
所以序列中 > 的个数就为 \(b_n\) / m。\(b_n\)为 b 序列的和。
则 <= 答案就为 n - \(b_n\) / m。
AC代码:
// -----------------
const int N = 1e6 + 10;
int a[N],s[N];
int k,n,m,x;
void solve()
{
cin >> k;
rep(i,1,k) cin >> a[i];
cin >> n >> m >> x;
rep(i,1,k) a[i] %= m;
rep(i,1,k) s[i] = s[i-1] + a[i];
int aa = s[k] % m;
int cc = s[k] / m;
int bb = n / k;
int num = 0;
num = bb * cc + (bb * aa + x % m) / m + s[n%k]/m;
cout << n-num << endl;
}
题目:C(博弈)
题意:
给你 n 堆石子,每次操作只能取 p 的幂次方个棋子,若先手胜则输出GOOD,否则输出BAD
思路:
博弈只能找规律了,首先我们可以写个暴力SG打表从中找出规律(因为暴力SG会爆掉,所以我们可以尝试优化SG函数):
若 p 为奇数:
- x 为奇 —— SG(x) = 1
- x 为偶 —— SG(x) = 0
p为偶数:
- x % (p + 1)
- x = p —— SG(x) = 2
- x 为奇数 —— SG(x) = 1
- x 为偶 —— SG(x) = 0
然后根据规律优化SG函数即可。
AC代码:
// -----------------
int n,p;
int sg(int x)
{
if(x == p) return 2;
if(x & 1) return 1;
else return 0;
}
void solve()
{
cin >> n >> p;
if(p & 1)
{
int res = 0;
rep(i,1,n)
{
int x;
cin >> x;
if(x & 1) res ^= 1;
else res ^= 0;
}
if(res) cout << "GOOD" << endl;
else cout << "BAD" << endl;
return;
}
int res = 0;
rep(i,1,n)
{
int x;
cin >> x;
res ^= sg(x%(p+1));
}
if(res) cout << "GOOD" << endl;
else cout << "BAD" << endl;
}
总结:
赛时5题结束,最后半个小时也没猜出C。唉,猜出就金了。可惜了。开始 B 的第一发因为没看清数据范围WA了一发,然后想了一下没那么简单就去看C了,同样因为数据范围暴力SG过不了又耗费了太多时间(完全被榜带歪了)。后面开完 J 后只剩半个小时了。想了想 B 可能因为边界问题半个小时可能调不出,就去疯狂交C了。早知道就应该去调 B 了。