Codeforces Round #956 (Div. 2)A->D题解

A

感觉十分抽象输出1->n就可以,赛事不知道怎么想的.....

​
LL n, A[110];
void solve()
{
  cin >> n;
  int st;
  if (n % 2 == 0)
    st = n / 2 + 1;
  else
    st = n / 2;
  for (int i = n; i >= st; i--)
  {
    A[i] = i;
  }
  for (int i = st - 1; i >= 1; i--)
  {
    LL sum = 0;
    for (int j = 2; j * i <= n; j++)
    {
      sum += A[j * i];
    }
    A[i] = i - (sum % i);
  }
  for (int i = 1; i <= n; i++)
  {
    cout << A[i] << " ";
  }
  cout << endl;
}

​

B

一开始没想到,后面手搓了一下不一样的时候只改一个2*2的矩阵, 发现可以猜了一发,AC

写的很屎

int n, m;
int A[N][N], B[N][N];
string C[N], D[N];
void solve()
{
  cin >> n >> m;
  for (int i = 1; i <= n; i++)
  {
    cin >> C[i];
    C[i] = " " + C[i];
  }
  for (int i = 1; i <= n; i++)
  {
    cin >> D[i];
    D[i] = " " + D[i];
  }
  LL num1 = 0, num2 = 0;
  for (int i = 1; i <= n; i++)
  {
    for (int j = 1; j <= m; j++)
    {
      A[i][j] = C[i][j] - '0';
    }
  }
  for (int i = 1; i <= n; i++)
  {
    for (int j = 1; j <= m; j++)
    {
      B[i][j] = D[i][j] - '0';
    }
  }
  for (int i = 1; i < n; i++)
  {
    for (int j = 1; j < m; j++)
    {
      if (A[i][j] != B[i][j])
      {
        if (A[i][j] < B[i][j])
        {
          if (B[i][j] - A[i][j] == 1)
          {
            A[i][j] += 1;
            A[i][j] %= 3;
            A[i][j + 1] += 2;
            A[i + 1][j] += 2;
            A[i + 1][j + 1] += 1;
            A[i][j + 1] %= 3;
            A[i + 1][j] %= 3;
            A[i + 1][j + 1] %= 3;
          }
          else
          {
            A[i][j] += 2;
            A[i][j] %= 3;
            A[i][j + 1] += 1;
            A[i + 1][j] += 1;
            A[i + 1][j + 1] += 2;
            A[i][j + 1] %= 3;
            A[i + 1][j] %= 3;
            A[i + 1][j + 1] %= 3;
          }
        }
        else
        {
          if (A[i][j] - B[i][j] == 1)
          {
            A[i][j] += 2;
            A[i][j] %= 3;
            A[i][j + 1] += 1;
            A[i + 1][j] += 1;
            A[i + 1][j + 1] += 2;
            A[i][j + 1] %= 3;
            A[i + 1][j] %= 3;
            A[i + 1][j + 1] %= 3;
          }
          else
          {
            A[i][j] += 1;
            A[i][j] %= 3;
            A[i][j + 1] += 2;
            A[i + 1][j] += 2;
            A[i + 1][j + 1] += 1;
            A[i][j + 1] %= 3;
            A[i + 1][j] %= 3;
            A[i + 1][j + 1] %= 3;
          }
        }
        // for (int a = 1; a <= n;a++)
        // {
        //   for (int b = 1; b <= m;b++)
        //   {
        //     cout << A[a][b] << "  ";
        //   }
        //   cout << endl;
        // }
        // cout << endl;
      }
    }
  }
  for (int i = 1; i <= n; i++)
  {
    for (int j = 1; j <= m; j++)
    {
      if (A[i][j] != B[i][j])
      {
        // cout << i << "    " << j << endl;
        cout << "NO" << endl;
        return;
      }
    }
  }
  cout << "YES" << endl;
}

C

一下就想到了二分俩次, 枚举他们三个的顺序,一共6种,写的很屎

int n;
LL A[N], B[N], C[N];
void solve()
{
  cin >> n;
  for (int i = 1; i <= n + 3; i++)
  {
    A[i] = 0;
    B[i] = 0;
    C[i] = 0;
  }
  LL sum = 0;
  for (int i = 1; i <= n; i++)
  {
    cin >> A[i];
    sum += A[i];
  }
  for (int i = 1; i <= n; i++)
    cin >> B[i];
  for (int i = 1; i <= n; i++)
    cin >> C[i];
  LL qq = 0;
  if (sum % 3 == 0)
    qq = sum / 3;
  else
    qq = sum / 3 + 1;
  for (int i = 1; i <= n; i++)
    A[i] += A[i - 1];
  for (int i = 1; i <= n; i++)
    B[i] += B[i - 1];
  for (int i = 1; i <= n; i++)
    C[i] += C[i - 1];
  int a1 = lower_bound(A + 1, A + 1 + n, qq) - A;
  int b1 = lower_bound(B + 1, B + 1 + n, qq + B[a1]) - B;
  if (C[n] - C[b1] >= qq && b1 < n)
  {
    cout << "1 " << a1 << " " << a1 + 1 << " " << b1 << " " << b1 + 1 << " " << n << endl;
    return;
  }
  b1 = lower_bound(C + 1, C + 1 + n, C[a1] + qq) - C;
  if (B[n] - B[b1] >= qq && b1 < n)
  {
    cout << "1 " << a1 << " " << b1 + 1 << " " << n << " " << a1 + 1 << " " << b1 << endl;
    return;
  }
  a1 = lower_bound(B + 1, B + 1 + n, qq) - B;
  b1 = lower_bound(A + 1, A + 1 + n, A[a1] + qq) - A;
  // cout << a1 << "     " << b1 << endl;
  if (C[n] - C[b1] >= qq && b1 < n)
  {
    cout << a1 + 1 << " " << b1 << " 1" << " " << a1 << " " << b1 + 1 << " " << n << endl;
    return;
  }
  b1 = lower_bound(C + 1, C + 1 + n, qq + C[a1]) - C;
  if (A[n] - A[b1] >= qq && b1 < n)
  {
    cout << b1 + 1 << " " << n << " 1 " << a1 << " " << a1 + 1 << " " << b1 << endl;
    return;
  }
  a1 = lower_bound(C + 1, C + 1 + n, qq) - C;
  b1 = lower_bound(A + 1, A + 1 + n, qq + A[a1]) - A;
  if (B[n] - B[b1] >= qq && b1 < n)
  {
    cout << a1 + 1 << " " << b1 << " " << b1 + 1 << " " << n << " 1" << " " << a1 << endl;
    return;
  }
  b1 = lower_bound(B + 1, B + 1 + n, qq + B[a1]) - B;
  if (A[n] - A[b1] >= qq && b1 < n)
  {
    cout << b1 + 1 << " " << n << " " << a1 + 1 << " " << b1 << " " << "1 " << a1 << endl;
    return;
  }
  cout << "-1" << endl;
}

D

想到只交换距离为1的, 交换会变化逆序对的个数?只有逆序对奇偶性相同的才有可能相同, 补题发现我赛时另外一个做法对的(判断一个变为另外一个的奇偶次),自己码错了,哭了

int n, A[N], B[N], C[N];
LL ans1, ans2;
void merge1(int low, int mid, int high)
{
  int i = low, j = mid + 1, k = low;
  while (i <= mid && j <= high)
  {
    if (A[i] <= A[j])
      B[k++] = A[i++];
    else
    {
      B[k++] = A[j++];
      ans1 = ans1 + mid - i + 1;
    }
  }
  while (i <= mid)
    B[k++] = A[i++];
  while (j <= high)
    B[k++] = A[j++];
  for (int i = low; i <= high; i++)
    A[i] = B[i];
}
void mergesort1(int x, int y)
{
  if (x >= y)
    return;
  int mid = (x + y) / 2;
  mergesort1(x, mid);
  mergesort1(mid + 1, y);
  merge1(x, mid, y);
}
void merge2(int low, int mid, int high)
{
  int i = low, j = mid + 1, k = low;
  while (i <= mid && j <= high)
  {
    if (C[i] <= C[j])
      B[k++] = C[i++];
    else
    {
      B[k++] = C[j++];
      ans2 = ans2 + mid - i + 1;
    }
  }
  while (i <= mid)
    B[k++] = C[i++];
  while (j <= high)
    B[k++] = C[j++];
  for (int i = low; i <= high; i++)
    C[i] = B[i];
}
void mergesort2(int x, int y)
{
  if (x >= y)
    return;
  int mid = (x + y) / 2;
  mergesort2(x, mid);
  mergesort2(mid + 1, y);
  merge2(x, mid, y);
}
void solve()
{
  ans1 = 0, ans2 = 0;
  cin >> n;
  map<int, int> D, E;
  for (int i = 1; i <= n; i++)
  {
    cin >> A[i];
    D[A[i]]++;
  }
  for (int i = 1; i <= n; i++)
  {
    cin >> C[i];
    E[C[i]]++;
  }
  for (auto y : D)
  {
    if (y.second != E[y.first])
    {
      cout << "NO" << endl;
      return;
    }
  }
  mergesort1(1, n);
  mergesort2(1, n);
  if ((ans1 & 1) == (ans2 & 1))
    cout << "YES" << endl;
  else
    cout << "NO" << endl;
}

感觉出的有点ex,ABCD不是很难,就是很麻烦

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值