杭电第八场题解

7220 - Theramore

题意

给定字符串s,任意次交换长度为奇数的连续子串,求最小字典序

思路

通过交换区间[l,r]和交换[l+1,r-1]可以实现 同奇偶位 的 数字互换

用两个vector存数字,sort后输出即可

代码

void solve()
{
  string s;
  cin >> s;
  vector<int> odd;
  vector<int> even;
  int l = s.length();
  for (int i = 0; i < l; i++)
  {
    if (i % 2)
      even.push_back(s[i] - '0');
    else
      odd.push_back(s[i] - '0');
  }
  sort(odd.begin(), odd.end());
  sort(even.begin(), even.end());
  for (int i = 0; i < odd.size(); i++)
  {
    cout << odd[i];
    if (i < even.size())
      cout << even[i];
  }
  cout << endl;
}

7223 - Quel'Thalas

题意

一个包含(0,0)到(n,n)的坐标系,最少绘制几条线能覆盖除(0,0)外的所有点

代码

void solve()
{
    int n;
    cin >> n;
    cout << 2 * n << endl;
}

7227 - Orgrimmar

题意

给定一棵树,求最多剩余节点数,使得每个节点的度小于等于1

思路

树状dp

代码

const int N = 5 * 1e5 + 5; // N点数
const int M = 2 * N;       // M边数

int n, m;    //输入点数、边数
int idx;     //实际边数
int head[N]; //以i为起点的第一条边的下标
int f[N][2][2];
struct Edge
{
    int to, next, w;
} edge[M]; // to边的终点 w边的权值 next同起点下一条边的下标

void add(int u, int v, int w)
{
    edge[idx].to = v;
    edge[idx].next = head[u];
    edge[idx].w = w;
    head[u] = idx++;
}

void dfs(int u, int fa)
{
    f[u][1][0] = f[u][0][0] = 0;
    f[u][1][1] = f[u][0][1] = 1;
    int sum = 0;
    for (int i = head[u]; i != -1; i = edge[i].next)
    {
        int to = edge[i].to;
        if (to == fa)
            continue;
        dfs(to, u);
        f[u][0][0] += max(f[to][0][1], f[to][0][0]);
        sum += f[to][1][0];
        f[u][1][0] += max(f[to][0][1], f[to][0][0]);
        f[u][1][1] += f[to][1][0];
    }
    f[u][0][1] += sum;
    for (int i = head[u]; i != -1; i = edge[i].next)
    {
        int to = edge[i].to;
        if (to == fa)
            continue;
        f[u][0][1] = max(f[u][0][1], 1 + sum - f[to][1][0] + f[to][1][1]);
    }
}
void solve()
{
    cin >> n;
    memset(head, -1, sizeof head);
    idx = 0;
    for (int i = 1; i < n; i++)
    {
        int u, v;
        cin >> u >> v;
        add(u, v, 0);
        add(v, u, 0);
    }
    dfs(1, -1);
    ll ans = max(max(f[1][0][0], f[1][0][1]), max(f[1][1][1], f[1][1][0]));
    cout << ans << endl;
}

7230 - Stormwind

题意

给定n*m的矩形,允许横向竖向切分,需保证所有小矩形体积大于等于k,求最多切分次数、

思路

枚举i*h的小矩形

代码

void solve()
{
   int n, m, k;
   cin >> n >> m >> k;
   int m_ = max(m, n), n_ = min(m, n);
   int res = 0;
   for (int i = 1; i <= m; i++)
   {
      int h = ceil(k * 1.0 / i);
      if (h > n)
         continue;
      int cnt = m / i - 1 + n / h - 1;
      res = max(res, cnt);
   }
   cout << res << endl;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值