25CCPC东北邀请赛vp补题

感觉还好 签到不难

F 枚举 暴力

枚举范围内每一个合法时间(最多6012=720个),难在计算角度
时针分针分别算, d e g h = 30 ∗ ( h + m 60 ) = 30 h + m 2 deg_h=30*(h+\frac{m}{60})=30h+\frac{m}{2} degh=30∗(h+60m)=30h+2m,有/2,可以把所有角度
2避免使用double

cpp 复制代码
int deg(int x,int y,int x0,int y0){
    int h=2*30*x+2*30*y/60,h0=2*30*x0+2*30*y0/60;
    int m=2*360*y/60,m0=2*360*y0/60;
    // double res=(6*min({fabs(y-y0),60-fabs(y-y0)})+30*min({fabs(h-h0),12-fabs(h-h0)}));
    int res=min(abs(h-h0),720-abs(h-h0))+min(abs(m-m0),720-abs(m-m0));
    return res;
}
void solve(){
    int x,y,x0,y0,x1,y1;cin>>x>>y>>x0>>y0>>x1>>y1;
    int ans=inf;
    int ax,ay;
    if(x0==x1){
        forr(j,y0,y1){
            int d=deg(x,y,x0,j);
            if(d<ans)ax=x0,ay=j,ans=d;
        }
    }else{
        forr(i,x0,x1){
            forr(j,(i==x0?y0:0),(i==x1?y1:59)){
                int d=deg(x,y,i,j);
                // cout<<i<<' '<<j<<' '<<d<<endl;
                if(d<ans)ax=i,ay=j,ans=d;
            }
        }
    }
    cout<<ax<<' '<<ay<<endl;
    
}

H 二分 配对

参考@Hongs_Cai 的题解

以下分析来自千问:

为什么直接把所有城市的"容纳能力"加起来得 s u m c a p a c i t y sum_{capacity} sumcapacity,只要 ≥ s u m b \geq sum_b ≥sumb就有解?

这是一个非常深刻的结论,基于本题的特殊结构:每组人只有一个城市不能去

  • 在这个特定的约束下,局部的容量限制之和如果大于等于总人数,那么一定存在一种分配方案。(因为 b i b_i bi可以散开分到不同城市)
  • 这其实隐含了霍尔婚嫁定理的结论。因为每组人只被一个城市拒绝,这种"排斥关系"非常稀疏。

霍尔婚嫁定理:来自@汪湜

通俗说法:任意k个人,他们总共能选择的对象集合大小必须至少是k,才能一人一个。

反例:如果有 3 个人,但他们加起来只认识 2 个对象,那么这 3 个人不可能每个人都匹配成功(必然有人落单)。这就是违反了霍尔条件。
对这个题来说,每组人只有一个城市不能去, s u m b sum_b sumb个人的能选择对象集合大小就是所有城市容纳能力的和 s u m c a p a c i t y sum_{capacity} sumcapacity,只要 s u m c a p a c i t y ≥ s u m b sum_{capacity}\geq sum_b sumcapacity≥sumb就有合理分配方式

注:如果每组人可以避开多个城市,这个贪心求和就不成立了,必须用网络流。但本题每组只避开一个,使得问题退化为简单的求和判断。

cpp 复制代码
void solve(){
  int n;cin>>n;
  int sb=0;
  vector<int>a(n+1),b(n+1),c(n+1);
  forr(i,1,n)cin>>a[i];
  forr(i,1,n){
    cin>>b[i];
    sb+=b[i];
  }
  forr(i,1,n)cin>>c[i];
  vector<int>mxb(n+1,sb);//根据相冲规则 每个城市预期最大的接纳人数
  forr(i,1,n){
    mxb[a[i]]-=b[i];//犯冲的不不接纳
  }

  auto check=[&](int x)->bool{
    vector<int>d(n+1);
    forr(i,1,n)d[i]=(x/c[i]); // 根据x的最大容量
    int s_cap=0; // 总的最大容量
    forr(i,1,n){
      s_cap+=min(d[i],mxb[i]);
    }
    if(s_cap<sb)return false; //小了
    else return true; // 大了
  };
  int l=0,r=inf;
  while (l<r)
  {
    int mid=(l+r)>>1;
    if(check(mid))r=mid;
    else l=mid+1;
  }
  cout<<r<<endl;
  
}

/*
 2
 2
 1 2
 3 4
 1 2
 5
 1 2 3 4 5
 5 4 3 2 1
 2 1 4 3 5
*/

L 大模拟

之后有空补...

相关推荐
MicroTech20255 小时前
突破虚时演化非酉限制:MLGO微算法科技发布可在现有量子计算机运行的变分量子模拟技术
科技·算法·量子计算
唐樽5 小时前
C++ 竞赛学习路线笔记
c++·笔记·学习
ShineWinsu5 小时前
对于Linux:文件操作以及文件IO的解析
linux·c++·面试·笔试·io·shell·文件操作
hssfscv5 小时前
软件设计师下午题六——Java的各种设计模式
java·算法·设计模式
珂朵莉MM6 小时前
第七届全球校园人工智能算法精英大赛-算法巅峰赛产业命题赛第3赛季优化题--多策略混合算法
人工智能·算法
罗西的思考6 小时前
【OpenClaw】通过 Nanobot 源码学习架构---(6)Skills
人工智能·深度学习·算法
枫叶林FYL6 小时前
【自然语言处理 NLP】7.2 红队测试与对抗鲁棒性(Red Teaming & Adversarial Robustness)
人工智能·算法·机器学习
qiqsevenqiqiqiqi6 小时前
字符串模板
算法
十五年专注C++开发6 小时前
Oat++: 一个轻量级、高性能、零依赖的 C++ Web 框架
开发语言·c++·web服务·oatpp
Fcy6486 小时前
算法基础详解(六)倍增思想与离散化思想
算法·快速幂·离散化·倍增算法