2023ICPC江西省赛补题(B,C)

发布时间 2023-05-22 21:38:27作者: 陌上&初安

题目: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 了。
银