返回顶部

Codeforces Round 909 (Div.3)

A. Game with Integers

思路

玩家二总是可以做玩家一的逆操作,所以只有可以一招制敌时,玩家一可以获胜,其他玩家二都可以拖入10局后

code

int n;
void solved()
{
    cin >> n;
    if (n % 3 == 0)
    {
        cout << "Second" << endl;
    }
    else
    {
        cout << "First" << endl;
    }
}

B. 250 Thousand Tons of TNT

思路

可以对\(n\)的因子进行暴力枚举,分别找出最大值和最小值,最后取最大答案

code

int n, a[N];
void solved()
{
    cin >> n;
    a[0] = 0;
    for (int i = 1; i <= n; ++i)
    {
        int tot;
        cin >> tot;
        a[i] = a[i - 1] + tot;
    }
    vector<int> ans;
    for (int i = n; i >= 2; --i)
    {
        int k = n / i;
        if (n % i == 0)
        {
            int b[n / k + 1] = {0}, num = 1;
            for (int j = k; j <= n; j += k)
            {
                b[num++] = a[j] - a[j - k];
            }
            ans.push_back(*max_element(b + 1, b + num) - *min_element(b + 1, b + num));
        }
    }
    int res = 0;
    for (auto i : ans)
    {
        if (i > res)
            res = i;
    }
    cout << res << endl;
}

C. Yarik and Array

思路

动态规划,最大子区间和变形,

首先判断上一个与当前的奇偶性是否相同,

相同\(dp[i]=a[i]\),

否则\(dp[i]=max(a[i],a[i]+dp[i-1])\)

code

int n, a[N];
void solved()
{
    cin >> n;
    int dp[n + 1] = {0};
    for (int i = 1; i <= n; ++i)
    {
        cin >> a[i];
    }
    dp[1] = a[1];
    for (int i = 2; i <= n; ++i)
    {
        if ((a[i] & 1) == (a[i - 1] & 1))
            dp[i] = a[i];
        else
            dp[i] = max(a[i], dp[i - 1] + a[i]);
    }
    cout << *max_element(dp + 1, dp + 1 + n) << endl;
}

D. Yarik and Musical Notes

思路

题目要求\((2^{a})^{2^b}=(2^b)^{2^a}\implies a*{2^b}=b*{2^a} \implies \frac{2^a}{a}=\frac{2^b}{b}\)

image-20231118231050241

观察可知有两种情况上面等式成立

1.\(a=1,b=2\)

2.\(a=b\)

计算每一类的\(num\),通过\(ans+=num*(num-1)/2\)求解

code

int n, a[N];
void solved()
{
    cin >> n;
    int num1 = 0, num2 = 0;
    for (int i = 1; i <= n; ++i)
    {
        cin >> a[i];
        if (a[i] == 1 || a[i] == 2)
            num1++;
    }
    int ans = 0;
    sort(a + 1, a + 1 + n);
    for (int i = 1; i <= n; ++i)
    {
        if (a[i] > 2)
        {
            int tot = a[i];
            while (a[i + 1] == tot && i < n)
            {
                i++;
                num2++;
            }
            ans += (num2 + 1) * num2 / 2;
            num2 = 0;
        }
    }
    ans += num1 * (num1 - 1) / 2;
    cout << ans << endl;
}

E. Queue Sort

思路

模拟操作可以发现当遇到数组中的最小值时,将没能操作其他数,因此可以将原始数组分成两点来看

1.最小值前,所有都要进行操作,所以最小前元素数目就是\(ans\)

2.最小值后,所有无法进行操作,所以后面是否有序决定了数组能否正确排序

code

int n, a[N];
void solved()
{
    cin >> n;
    for (int i = 1; i <= n; ++i)
    {
        cin >> a[i];
    }
    int pos = min_element(a + 1, a + 1 + n) - a;
    for (int i = pos; i < n; ++i)
    {
        if (a[i] > a[i + 1])
        {
            cout << -1 << endl;
            return;
        }
    }
    cout << pos - 1 << endl;
}

F. Alex's whims

思路

首先构造一条链的树,其次可以发现移动最后一个元素的位置可以任意构造\(1\sim n-1\)的一条链(从根节点到最后一元素)

20231118

code

int n, q;
int d[N];
void solved()
{
    cin >> n >> q;
    for (int i = 1; i <= q; ++i)
    {
        cin >> d[i];
    }
    for (int i = 2; i <= n; ++i)
    {
        cout << i - 1 << " " << i << endl;
    }
    int last = n - 1;
    for (int i = 1; i <= q; ++i)
    {
        if (last == d[i])
        {
            cout << -1 << " " << -1 << " " << -1 << endl;
        }
        else
        {
            cout << n << " " << last << " " << d[i] << endl;
            last = d[i];
        }
    }
}
posted @ 2023-11-19 00:02  bhxyry  阅读(32)  评论(0)    收藏  举报