Codeforces Round #829 (Div. 2)题解

文章目录

  • A
  • B
  • C1
  • C2
  • D

A

题意:给我们一个字符串,Q代表问题A代表答案,问题可能会一直提,答案可能会晚些回复。问我们能不能保证一个问题后面至少会跟着一个回答。

思路:我们边遍历边看就行。

#include 
#include 
#include 
using namespace std;

void solve()
{
    int n;
    string s;
    cin >> n >> s;
    int A = 0, Q = 0;
    for (int i = 0; i < n; i++)
    {
        if (s[i] == 'Q')
        {
            Q++;
        }
        else if (Q && s[i] == 'A')
        {
            Q--;
        }
    }
    if (Q == 0)
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int T;
    cin >> T;
    while (T--)
    {
        solve();
    }
    return 0;
}

B

题意:给我们一个数n然后我们要用小于等于n的数构造一个数组使相邻的两个之间的差绝对值的最小值最大。(每个数只能用一遍且必须用一遍)。

思路:这个题的话我们可以考虑前后配对。例如一个偶数6.我们可以让步4和1进行配对。5和2进行配对。6和3进行配对。这样的话一定是最小值最大的。奇数的话我们只需要把最后一个数放到最后前面的按偶数来即可。

void solve()
{
    memset(st, false, sizeof st);
    int n;
    cin >> n;
    if (n % 2 == 1)
    {
        int k = n / 2;
        for (int i = n / 2 + 1; i <= n; i++)
        {
            if (st[i] == false)
            {
                int j = i;
                while (j >= 1)
                {
                    if (st[j] == false)
                    {
                        st[j] = true;
                        cout << j << ' ';
                        j -= k;
                    }
                    else
                    {
                        break;
                    }
                }
            }
            else
            {
                break;
            }
        }
        cout << endl;
    }
    else
    {
        int k = n / 2;
        for (int i = n / 2 + 1; i <= n; i++)
        {
            if (st[i] == false)
            {
                int j = i;
                while (j >= 1)
                {
                    st[j] = true;
                    cout << j << ' ';
                    j -= k;
                }
            }
            else
            {
                break;
            }
        }
        cout << endl;
    }
}

signed main()
{
    IOS;
    int T;
    cin >> T;
    while (T--)
    {
        solve();
    }
    return 0;
}

C1

题意:这个题的话是给我们一个由1和-1组成的数组,让我们把他分成任意段,然后每一段内的奇数位+偶数位-。让我们看看能不能构造一个数组让所有段相加之和为0。

思路:这个题的话我们可以发现如果相加是奇数的话一定是不可以的。为偶数的话肯定是可以的。相邻的两个一样的话根据运算的规则肯定就为0。所以如果连续一样的1或者-1的话,并且是偶数个连续的话就把他们分成一组那么本组一定是0。剩下的把每一个-1和1都单独分成一组这样的话,它一定是有解的因为和是偶数。

#include 
#include 
#include 
#include 
using namespace std;

const int N = 1e6 + 10;
int a[N];
vector> ans;

void solve()
{
    ans.clear();
    int n;
    cin >> n;
    int sum = 0;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        sum += a[i];
    }
    if (sum % 2 != 0)
    {
        cout << -1 << endl;
        return;
    }
    for (int i = 1; i <= n; i++)
    {
        if (a[i] == 1 && a[i + 1] == -1 || a[i] == -1 && a[i + 1] == 1)
        {
            ans.push_back({i, i});
            ans.push_back({i + 1, i + 1});
            i++;
        }
        else
        {
            int state = a[i];
            int j = i;
            int k = 0;
            while (state == a[j] && j <= n)
            {
                k++;
                j++;
            }
            /* if (i == 5)
                cout << k << endl; */
            if (k % 2 == 0)
            {
                ans.push_back({i, j - 1});
                i = j - 1;
            }
            else
            {
                ans.push_back({i, j - 2});
                i = j - 2;
            }
        }
    }
    cout << ans.size() << endl;
    for (int i = 0; i < (int)ans.size(); i++)
    {
        cout << ans[i].first << ' ' << ans[i].second << endl;
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int T;
    cin >> T;
    while (T--)
    {
        solve();
    }
    return 0;
}

C2

题意:跟C1一样的只不过数组可以存在0元素

思路:如果中间有元素0,判断相邻非0元素是否相等, 若相等左边自成区间,右边带一个0自成区间,若不相等则自成区间;若中间没有0,则和C1情况相同

D

题意:给我们一个数组和一个x,让我们看看数组内每一个数的阶乘相加能否整除x的阶乘。

思路:暴力的话肯定是不行的,会爆。我们可以发现(i+1)个i的阶乘就是i+1的阶乘。这样的话,我们其实就可以统计一下a[i]的个数然后枚举一下1~x之间的数,如果此时有余数的话就说明是不行的。最后保证cnt[x]不是零并且前面全是零的话就是可以的。

#include 
#include 
#include 
using namespace std;

const int N = 5e5 + 10;
int cnt[N];

int main()
{
     int n, x;
     cin >> n >> x;
     for (int i = 1; i <= n; i++)
     {
          int x;
          cin >> x;
          cnt[x]++;
     }
     int flag = 1;
     for (int i = 1; i < x; i++)	//枚举1~x的数
     {
          cnt[i + 1] += cnt[i] / (i + 1);		//统计一下(i+1)的阶乘的个数
          if (cnt[i] % (i + 1) != 0)	//如果不等于零的话,就说明有余数,最后肯定除不尽
          {
               flag++;
               break;
          }
     }
     if (flag == 1 && cnt[x] != 0)
     {
          cout << "Yes" << endl;
     }
     else
     {
          cout << "No" << endl;
     }
     return 0;
}

你可能感兴趣的:(Codeforces补题,算法,c++,数据结构)