CF每日4题(1300-1400)

2026B 贪心 1300

我的思路和dalao很像

cpp 复制代码
void solve(){
	int n;cin>>n;
	vector<int>a(n+1);
	forr(i,1,n)cin>>a[i];
	int fg=(n&1),ans;
	if(fg){
		ans=1e18+10;
		forr(i,1,n){//枚举把一个数去掉,其他两两组合
			int tmp=1,j=1;
			while (j<=n)
			{
				if(j==i)j++;
				int pre=a[j++];
				if(j==i)j++;
				if(j>n)break;
				int now=a[j++];
				if(j==i)j++;
				tmp=max(now-pre,tmp);
			}
		
			ans=min(ans,tmp);
		}
		cout<<ans<<endl;
	}else{
		ans=0;
		for(int i=2;i<=n;i+=2){
			ans=max(a[i]-a[i-1],ans);
		}
		cout<<ans<<endl;
	}
}

2033E 思维 贪心 1400

题意:

  • 原始数列两两调换位置,让每个数满足 p i = i , p p i = i p_i=i,p_{p_i}=i pi=i,ppi=i
  • 就是下标 i i i指向下标 p i p_i pi,形成自己指自己、两个互指

思路:把题意抽象成环

  • 交换就是改变一对儿边的指向,一个有x点的环要形成 ⌈ x 2 ⌉ = x + 1 2 \lceil {x\over 2}\rceil={{x+1}\over2} ⌈2x⌉=2x+1个小环,需要变 x + 1 2 − 1 {{x+1}\over2}-1 2x+1−1条边
cpp 复制代码
const int N=1e6+10;
//并查集
int fa[N],cnt[N];
int find(int x){
    if(fa[x]==x)return x;
    return fa[x]=find(fa[x]);
}
void merge(int x,int y){
    int fx=find(x),fy=find(y);
    if(fx==fy)return;
    if(x!=y)cnt[fx]+=cnt[fy],fa[fy]=fx;
}
void solve()
{
    int n;
    cin>>n;
    forr(i,1,n)fa[i]=i,cnt[i]=1;
    vector<int>p(n+1);
    forr(i,1,n){
        cin>>p[i];
        merge(i,p[i]);//建环
    }
    int ans=0;
    forr(i,1,n){
        if(fa[i]==i){
            ans+=(cnt[i]-1)/2;
        }
    }
    cout<<ans<<endl;

}

2013C 交互题 思维 1400

注意找子串是在全串中匹配,一开始犯傻以为是从字符串首开始匹配的...

  • 向后加0/1(加到厌倦),直到不是子串
  • 不匹配后向前拓展,就得到了目标字符串
cpp 复制代码
int query(string s){
    cout<<"? "<<s<<endl;
    cout.flush();
    int ans;cin>>ans;
    return ans;
}
void solve()
{
    int n;cin>>n;
    int len=0;
    string s="";
    //向后找
    while (len<n)
    {
        if(query(s+'0')){
            s+='0';len++;
            continue;
        }
        if(query(s+'1')){
            s+='1';len++;
            continue;
        }else{
            break;//添1添0都不是子串 向后加的加完了
        }
    }
    //向前加
    while (len<n)
    {
        if(query('0'+s)){
            s='0'+s;len++;
            continue;
        }
        s='1'+s;len++;
    }
    cout<<"! "<<s<<endl;
}

1967A 思维 贪心 1400

思路:最大化最小值,然后分配

最大化最小值怎么操作很犯难,于是看了题解

cpp 复制代码
void solve()
{
    int n,k;cin>>n>>k;
    vector<int>a(n+1);
    forr(i,1,n)cin>>a[i];
    sort(a.begin()+1,a.end());
    int sum=0,rg,wst;
    forr(i,1,n){
        sum+=a[i];
        if(a[i]*i-sum<=k)rg=i,wst=a[i]*i-sum;
    }
    k-=wst;
    int div=k/rg;//剩下的再均分
    int rst=k%rg;//均分后剩下的
    int minn=a[rg]+div;//最大化的最小值 多个较少的值平均后相等
    
    // cout<<"!!!"<<endl;
    // forr(i,1,rg)cout<<minn<<' ';
    // forr(i,rg+1,n)cout<<a[i]<<' ';cout<<endl;

    // cout<<(minn-1)*n+1<<endl;//较少的值排列组合的贡献 末尾的一组只能贡献1个
    // cout<<n-rg<<endl;//较大的值剩下的
    // cout<<rst<<endl;//k分配完后剩下的
    // cout<<endl;
    cout<<(minn-1)*n+1+(n-rg+rst)<<endl;
}
相关推荐
JAVA面经实录91721 小时前
Java企业级工程化·终极完整版背诵手册(无遗漏、全覆盖、面试+落地通用)
java·开发语言·面试
王老师青少年编程1 天前
csp信奥赛C++高频考点专项训练之贪心算法 --【哈夫曼贪心】:合并果子
c++·算法·贪心·csp·信奥赛·哈夫曼贪心·合并果子
周杰伦fans1 天前
AutoCAD .NET 二次开发:深入理解 EntityJig 的工作原理与正确实现
开发语言·.net
叼烟扛炮1 天前
C++第二讲:类和对象(上)
数据结构·c++·算法·类和对象·struct·实例化
天疆说1 天前
【哈密顿力学】深入解读航天器交会最优控制中的Hamilton函数
人工智能·算法·机器学习
wuweijianlove1 天前
关于算法设计中的代价函数优化与约束求解的技术7
算法
leoufung1 天前
LeetCode 149: Max Points on a Line - 解题思路详解
算法·leetcode·职场和发展
样例过了就是过了1 天前
LeetCode热题100 最长公共子序列
c++·算法·leetcode·动态规划
HXDGCL1 天前
矩形环形导轨:自动化循环线的核心运动单元解析
运维·算法·自动化
Bat U1 天前
JavaEE|多线程初阶(七)
java·开发语言