首页 > 其他分享 >HDU 暑假多校 2023 第四场

HDU 暑假多校 2023 第四场

时间:2023-07-28 10:48:06浏览次数:42  
标签:HDU ch 第四场 数列 int 多校 le include getchar

目录

写在前面

补题地址:https://acm.hdu.edu.cn/listproblem.php?vol=64,题号 7312~7323。

我是飞舞。

小子们哪,你们要自守,远避偶像。
Dear children, keep yourselves from idols.
——约翰一书

以下按照个人向难度排序。

7317

签到,特判 \(n = 2\)。

//
/*
By:Luckyblock
*/
#include <cmath>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define LL long long
//=============================================================
//=============================================================
inline int read() {
  int f = 1, w = 0; char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0'); 
  return f * w;
}
//=============================================================
int main() {
  // freopen("1.txt", "r", stdin);
  int T = read();
  while (T --) {
    int n = read();
    double ans1 = 0, ans2 = 2.0;
    if (n == 2) {
      ans1 = 1.0, ans2 = 1.0;
      printf("%.9lf %.9lf\n", ans1, ans2);
      continue;
    }
    LL k = 1ll * n * (n - 1) / 2;
    ans1 = (n - 1) + 2.0 * (k - n + 1);
    ans1 /= 1.0 * k;
    printf("%.9lf %.9lf\n", ans1, ans2);
  }
  return 0;
}

7323

发现 Alice 取走一个物品可以让自己获得 \(a\) 的贡献并让对方获得 \(-b\) 的贡献,Bob 取走一个物品可以让自己获得 \(b\) 的贡献并让对方获得 \(-a\) 的贡献,于是将物品按照 \(a+b\) 排序,两个人轮流按顺序拿即可。

//
/*
By:Luckyblock
*/
#include <cmath>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define LL long long
const int kN = 1e5 + 10;
//=============================================================
int n;
struct AdmireVega {
  LL a, b, delta;
} a[kN];
//=============================================================
inline int read() {
  int f = 1, w = 0; char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0'); 
  return f * w;
}
bool cmp(AdmireVega fir_, AdmireVega sec_) {
  return fir_.delta > sec_.delta;
}
//=============================================================
int main() {
  // freopen("1.txt", "r", stdin);
  int T = read();
  while (T --) {
    n = read();
    for (int i = 1; i <= n; ++ i) {
      int x = read(), y = read();
      a[i] = (AdmireVega) {x, y, x + y};
    }
    std::sort(a + 1, a + n + 1, cmp);
    LL suma = 0, sumb = 0;
    for (int i = 1; i <= n; ) {
      if (i <= n) suma = suma + a[i].a, ++ i;
      if (i <= n) sumb = sumb + a[i].b, ++ i;
    } 
    printf("%lld\n", suma - sumb);
  }
  return 0;
}

7314

\(T\) 组数据,每组数据给定 \(k\) 个数列 \(a_1\sim a_k\),第 \(i\) 个数列 \(a_i\) 长度为 \(c_i\)。现要求从每个数列中选择一个数构成一大小为 \(k\) 的集合 \(b\),要求最小化 \(\max\{b_i\} - \min\{b_i\}\)。
\(1\le T\le 10^6\),\(1\le k\le 10^6\),\(\sum c_i\le 10^6\),\(\sum \sum c_i\le 4\times 10^6\)。
3S,256MB。

学到许多。

很显然的想法是枚举 \(m = \max\{b_i\}\) 并且最大化 \(\min\{b_i\}\)。但是发现我们无法在原有的 \(k\) 个数列的结构上快速检查是否可以从每个数列中选择出最大的不大于 \(m\) 的数。

于是不得不考虑换一种存储结构。发现我们仅关注能否从每个数列中选择一个不大于 \(m\) 的数并最大化这个数的最小值,意味着我们可以把那些介于这两个值之间的数也全部看做已选择,即从每个数列中选择的个数 \(\ge 1\)。

于是考虑对于所有数,记录他们位于的数列的编号,再合并成一个有序数列。然后考虑尺取法,枚举滑动窗口的右端点,即枚举 \(m = \max\{b_i\}\),保证滑动的窗口中每个数列中的数至少有一个的情况下单调右移左端点即可最大化 \(\min\{b_i\}\)。

总时间复杂度 \(O\left(T\sum c_i\log (\sum c_i)\right)\) 级别。

//
/*
By:Luckyblock
*/
#include <cmath>
#include <cstdio>
#include <cctype>
#include <vector>
#include <cstring>
#include <algorithm>
#define pr std::pair
#define mp std::make_pair
const int kN = 1e6 + 10;
const int kInf = 2e9 + 2077;
//=============================================================
int k, num, sumc, cnt[kN];
int ans;
std::vector <pr <int, int> > a;
//=============================================================
inline int read() {
  int f = 1, w = 0; char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0'); 
  return f * w;
}
void Init() {
  ans = kInf;
  num = sumc = 0;
  a.clear();

  k = read();
  for (int i = 1; i <= k; ++ i) {
    cnt[i] = 0;

    int c = read();
    sumc += c;
    for (int j = 1; j <= c; ++ j) {
      int x = read();
      a.push_back(mp(x, i));
    }
  }
  std::sort(a.begin(), a.end());

}
void Solve() {
  int l = 0, r = -1;
  while (num < k) {
    ++ r;
    if (!cnt[a[r].second]) ++ num;
    cnt[a[r].second] ++;
  }
  while (l <= r) {
    if (cnt[a[l].second] == 1) break;
    cnt[a[l].second] --;
    ++ l;
  }
  ans = std::min(ans, a[r].first - a[l].first);

  while (r < sumc - 1) {
    ++ r;
    cnt[a[r].second] ++;
    while (l <= r) {
      if (cnt[a[l].second] == 1) break;
      cnt[a[l].second] --;
      ++ l;
    }
    ans = std::min(ans, a[r].first - a[l].first);
  }
}
//=============================================================
int main() {
  // freopen("1.txt", "r", stdin);
  int T = read();
  while (T --) {
    Init();
    Solve();
    printf("%d\n", ans);
  }
  return 0;
}

7321

呃呃手玩题。

只有一个人就是容易被手玩题薄纱。

钦定 \(n\le m\),首先当 \(n=1\) 时,答案即 \(\left\lfloor \frac{m+1}{2} \right\rfloor\)。

对于 \(n\ge 2\),发现可以在大多数情况下没有其他影响地消掉一个 \(1\times 3\) 的结构,即 \(n\times m\) 的结构可以转化为 \(n\times (m-3)\) 的结构1。大力手玩之后发现所有情况都可以变为 \(1\le n\le m\le 3\) 的情况。

于是特判一下即可。详见代码。

//
/*
By:Luckyblock
*/
#include <cmath>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
//=============================================================
//=============================================================
inline int read() {
  int f = 1, w = 0; char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0'); 
  return f * w;
}
//=============================================================
int main() {
  // freopen("1.txt", "r", stdin);
  int T = read();
  while (T --) {
    int n = read(), m = read(), ans = 0;
    if (n > m) std::swap(n, m);
    if (n == 1) {
      ans = (m + 1) / 2;
    } else if (n == 2) {
      if (m % 3) ans = 1;
      else ans = 2;
    } else {
      if (n % 3 == 0 || m % 3 == 0) ans = 2;
      else ans = 1;
    }
    printf("%d\n", ans);
  }
  return 0;
}

7322

7318

写在最后

学到了什么

  • 从每个集合中选一个有时可以转化为从每个集合选不小于 1 个,根据单调性可以变成至少选若干种的序列问题。
  • 手玩题扔给队友做。

标签:HDU,ch,第四场,数列,int,多校,le,include,getchar
From: https://www.cnblogs.com/luckyblock/p/17586948.html

相关文章

  • HDU1702 ACboy needs your help again! 题解
    #include<iostream>#include<string>#include<queue>#include<stack>usingnamespacestd;intt,n,m;intmain(){cin>>t;while(t--){queue<int>q;stack<int>s;stringop,str......
  • HDU4841 AHOI1999 圆桌问题 题解
    朴素的约瑟夫问题,用vector处理即可#include<iostream>#include<vector>usingnamespacestd;//AHOI1999圆桌问题类似于约瑟夫问题vector<int>table;intn,m;intmain(){while(cin>>n>>m){table.clear();for(inti=0;......
  • HDU−4825 XorSum
    01trie树定义:将整数转化为二进制再插入trie树,通常是从高位到低位插入trie。使用场景:寻找与异或相关的结果题目背景:Zeus和Prometheus做了一个游戏,Prometheus给Zeus一个集合,集合中包含了N个正整数,随后Prometheus将向Zeus发起M次询问,每次询问中包含一个正整数S,之后......
  • HDU 暑假多校 2023 第三场
    目录写在前面731073047311写在最后写在前面补题地址:https://acm.hdu.edu.cn/listproblem.php?vol=64,题号7300~7311。坐牢场。老东西怎么还在圈里混啊(恼以下按个人向难度排序,标题为题库中题号。7310模拟这个过程。缩放至\(Z\%\)即将原来的某个像素覆盖的范围\((x-1,y-1......
  • 杭电多校2023 第三场
    1005直接dp即可#include<bits/stdc++.h>usingnamespacestd;intdp[5005][5005];intN;inta[5005];constintMOD=1e9+7;intmain(){intT;cin>>T;while(T--){intN;memset(dp,0,sizeof(dp));dp[1][1]=......
  • 2023牛客多校7.24补题
    J-FineLogic题意:给定n个点和m对偏序关系(x,y),构造最少的排列数目k,使得在这k个排列中至少有一个排列满足x出现在y的前面。分析:很考验思维的一道题,首先如果m对偏序关系不构成环,也就是一张有向无环图,于是用拓扑排序构造出一个合理排列即可。要是有环,就直接构造两个排列,一个是1<2<.......
  • HDU4738 Caocao's Bridges
    \(HDU4738\)\(Caocao\)'\(s\)\(Bridges\)一、题目描述曹操在长江上建立了一些点,点之间有一些边连着。如果这些点构成的无向图变成了连通图,那么曹操就无敌了。刘备为了防止曹操变得无敌,就打算去摧毁连接曹操的点的桥。但是诸葛亮把所有炸弹都带走了,只留下一枚给刘备。所以刘......
  • 暑假牛客多校第三场 2023-7-24
    未补完A.WorldFragmentsI算法:构造做法:从x中某一个数位选一个数,这个数有可能是0或者是1。求x变到y的最小数,这个数有可能是负数,要取绝对值。注意如果x是0,那么从x中取的数就只有0了,除非y也等于0,否则输出-1。code#include<iostream>#include<cstring>#include<algori......
  • 牛客暑假多校 2023 第三场
    写在前面比赛地址:https://ac.nowcoder.com/acm/contest/57357。发生了这种事……气槽她气得吐槽了啊!以下按个人向难度排序。A签到。除非\(x=0\)否则可以调整为任意数,步数即两数之差。///*By:Luckyblock*/#include<cmath>#include<cstdio>#include<cctype>#incl......
  • 牛客多校2023 第三场
    A签到,注意$0$的特判#include<bits/stdc++.h>usingnamespacestd;longlongx,y;intmain(){strings1,s2;cin>>s1;cin>>s2;intLen1=s1.length();intLen2=s2.length();for(inti=0;i<Len1;i++)......