CF1057 BCD - 教程

仪表板 - Codeforces 第 1057 轮(第 2 组) - Codeforces — Dashboard - Codeforces Round 1057 (Div. 2) - Codeforces

B. Bitwise Reversion

题意:给定x,y,z;考虑是否存在a&b=x,b&c=y,a&c=z。

思路:按位分类讨论,发现如果有且仅有两个数同一位为1,比如x y最高位为1,那么a b c最高位都要为1,但是那样又不能满足a&c在这一位为0了。故无解。

void solve()
{
cin >> x >> y >> z;
rep(0, i, 32)
{
num = 0;
if ((x >> i & 1) + (y >> i & 1) + (z >> i & 1) == 2)
{
no;
re;
}
}
yes;
}

C. Symmetrical Polygons

题意:给一些边,保证组成的图像具有对称性和可连接性。求最大周长。

思路:

先考虑对称性:出现的偶数次可以放在两边;奇数次算剩下多余的一个,最多可以上下放一个,类比等腰梯形。

再考虑可连接性,类比三角形两边之和大于第三边,我们分别考虑选一条奇数边和两条奇数边,都要保证最长的那条奇数边<其余之和。

void solve()
{
cin >> n;
vector<int> c(n + 1);
  rep(1, i, n)
  {
  cin >> c[i];
  }
  map<int, int> pre;
    rep(1, i, n)
    {
    pre[c[i]]++;
    }
    vector<int> vec;
      sum = 0;
      for (auto &[val, cnt] : pre)
      {
      if (cnt % 2 == 0)
      {
      sum += val * cnt;
      }
      else
      {
      sum += val * ((cnt)-1);
      vec.emplace_back(val);
      }
      }
      if (sum == 0)
      {
      cout << 0;
      re;
      }
      sort(all(vec));
      if ((int)vec.size() <= n - 4) //前面sum加的都是偶数,所以此时至少要有四条边才有赋值
      {
      ans = sum;
      }
      else
      {
      ans = 0;
      }
      for (auto i : vec)  //考虑选一条奇数边
      {
      if (sum > i)
      ans = max(ans, sum + i);
      }
      if(vec.size()>=2)   //考虑选两条奇数边
      for (int i = 0; i < vec.size() - 1; i++)
      {
      if (sum + vec[i] > vec[i + 1])
      {
      ans = max(ans, sum + vec[i] + vec[i + 1]);
      }
      }
      cout << ans;
      }

D. Not Alone

题意:给一个数组,每次可以对任意一个数 ± 1 \pm1 ±1,问保证每个数都存在相邻位置和它一样的数(环形),最少操作次数是多少?

思路:先不考虑环形,考虑简单的链状,任意n可以拆成2x+3y,所以我们可以把数组拆成2、3的块相连。

我们令dp[i]为从1到i的最小操作次数,容易得到转移方程:

d p [ i ] = m i n ( d p [ i − 2 ] + c o s t 1 , d p [ i − 3 ] + c o s t 2 ) dp[i]=min(dp[i-2]+cost1,dp[i-3]+cost2) dp[i]=min(dp[i2]+cost1,dp[i3]+cost2) ,cost1表示i-1操作到i的次数,cost2表示操作i-2、i-1、i相等的最少次数。

现在考虑环形的限制,环形无非就是首尾一部分可以相连,显然对答案有影响的只有后三位,所以我们将所有数循环左移三次。

void solve()
{
cin >> n;
rep(1, i, n)
{
cin >> a[i];
}
ans = 1e18;
auto w = [&](int x, int y, int z)  //cost2
{
auto mx = max({x, y, z});
auto mi = min({x, y, z});
return mx - mi;
};
rep(0, i, 3)
{
dp[0] = 0;
dp[1] = inf;
rep(2, j, n)
{
dp[j] = dp[j - 2] + abs(a[j - 1] - a[j]);
if (j >= 3)
{
dp[j] = min(dp[j], dp[j - 3] + w(a[j - 2], a[j - 1], a[j]));
}
}
ans = min(ans, dp[n]);
rotate(a + 1, a + 2, a + n + 1);  //循环左移
}
cout << ans;
}
posted @ 2025-11-09 12:59  yangykaifa  阅读(6)  评论(0)    收藏  举报