当前位置: 首页 > article >正文

Educational Codeforces Round 176 (Rated for Div. 2)(A-D)

题目链接:Dashboard - Educational Codeforces Round 176 (Rated for Div. 2) - Codeforces

A. To Zero

思路

发现如果一个偶数-偶数结果是偶数,那么n如果是个奇数就让它减去k变成偶数,之后一直减k-1即可直到减为0

代码

void solve(){
    int n,k;
    cin>>n>>k;
    int cnt=0;
    if(n%2){
        n-=k;
        cnt++;
    }
    if(n%(k-1))
        cout<<cnt+n/(k-1)+1<<"\n";
    else
        cout<<cnt+n/(k-1)<<"\n";
}

B. Array Recoloring

思路

我们发现只有k=1的时候是有限制的,其他的无论什么情况总是能把前k+1个最大的给弄出来,

k=1时,如果k不在两头我们只能在最开始选择最大的,然后再选择两边最大的那个

如果k在两头,我们最开始选择第二大的,然后在让最大的最后染色即可

代码

#include<bits/stdc++.h>
using namespace std;

#define vcoistnt ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); 
#define int long long
#define vi vector<int>
#define vb vector<bool>
typedef pair<int,int> pll;

const int N=2e5+10;
const int inf=1e18;
const int mod=998244353;

void solve(){
    int n,k;
    cin>>n>>k;
    vi a(n+10);
    int mx=0;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        mx=max(a[i],mx);
    }
    if(k==1){
        if(a[1]==mx||a[n]==mx){
            sort(a.begin()+1,a.begin()+1+n);
            cout<<mx+a[n-1]<<"\n";
        }else{
            cout<<mx+max(a[1],a[n])<<"\n";
        }
    }else{
        int sum=0;
        sort(a.begin()+1,a.begin()+1+n);
        for(int i=n;i>=n-k;i--){
            sum+=a[i];
        }
        cout<<sum<<"\n";
    }
    
}
signed main() {
    vcoistnt
    cout<<fixed<<setprecision(2);
    int _=1;
    cin>>_;
    while(_--) solve();
    return 0;
}

C. Two Colors

思路

木板要求恰好只有两种颜色,且要求a[i]<=n的,且颜色连续

设当前木板涂有有两种油漆数量为x,y,我们发现 x+y>=n ,其次只涂这两种颜色的方法有(x+y-n+1)*2  乘2是将两种颜色倒转,但当x==n或y==n我们需要将木板只包含一种颜色的情况给减掉

此题要用到二分以及前后缀和的优化,不然会T4

代码

#include<bits/stdc++.h>
using namespace std;

#define vcoistnt ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); 
#define int long long
#define vi vector<int>
#define vb vector<bool>
typedef pair<int,int> pll;

const int N=2e5+10;
const int inf=1e18;
const int mod=998244353;

void solve(){
    int n,m;
    cin>>n>>m;
    vi a(m+10);
    for(int i=1;i<=m;i++){
        cin>>a[i];
    }
    sort(a.begin()+1,a.begin()+1+m);

    vi suf(m+10,0);     //表示后缀和
    vi ctn(m+10,0);     //表示i之后有几个a[i]==n的数
    for(int i=m;i>=1;i--){
        ctn[i]=ctn[i+1];
        if(a[i]==n) ctn[i]++; 
        suf[i]=suf[i+1]+a[i];
        
    }
    int cnt=0;

    /*未用后缀和优化的部分*/
    // for(int i=1;i<=m;i++){
    //     int p=lower_bound(a.begin()+1+i,a.begin()+1+m,n-a[i])-a.begin();
    //     if(p==m+1) continue;
    //     for(int j=p;j<=m;j++){
    //         if(a[i]!=n&&a[j]!=n)
    //             cnt+=(a[i]+a[j]-n+1)*2;
    //         else{
    //             cnt+=(a[i]+a[j]-n+1)*2;
    //             if(a[i]==n) cnt-=2;
    //             if(a[j]==n) cnt-=2;
    //         }
    //     }
    // }

    for(int i=1;i<=m;i++){

        int p=lower_bound(a.begin()+1+i,a.begin()+1+m,n-a[i])-a.begin();
        //找到第一个与a[i]相加大于n的数
        if(p==m+1) continue;
        cnt+=( suf[p]+(m-p+1)*(a[i]-n+1) )*2;

        cnt-=ctn[i+1]*2;
        if(a[i]==n){
            cnt-=(m-p+1)*2;
        }
    }

    cout<<cnt<<"\n";
}
signed main() {
    vcoistnt
    cout<<fixed<<setprecision(2);
    int _=1;
    cin>>_;
    while(_--) solve();
    return 0;
}

D. Equalization

思路

此题要变成x=y,可以发现我们要将x与y最终变成二进制下相等的前缀,那么我们现在可以明确目标是求将x二进制下右移i位,y二进制下右移j位,使得x=y的最小代价,不妨设

dp[i][j]表示x右移i位,y右移j位的最小代价,此题便变成了01背包求最小代价

代码

#include<bits/stdc++.h>
using namespace std;

#define vcoistnt ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); 
#define int long long
#define vi vector<int>
#define vb vector<bool>
typedef pair<int,int> pll;

const int N=2e5+10;
const int inf=1e18;
const int mod=998244353;


vector<vi> dp(75,vi(75,inf));

void init(){
    dp[0][0]=0;

    for(int k=1;k<=60;k++){
        for(int i=70;i>=0;i--){
            for(int j=70;j>=0;j--){
                if(i>=k) dp[i][j]=min(dp[i][j],dp[i-k][j]+(1ll<<k));
                if(j>=k) dp[i][j]=min(dp[i][j],dp[i][j-k]+(1ll<<k));
            }
        }
    }
}


void solve(){
    int x,y;
    cin>>x>>y;

    vi ax(75);
    vi ay(75);
    int ct1=0;
    int ct2=0;
    while(x){
        ax[++ct1]=x&1;
        x>>=1;
    }
    while(y){
        ay[++ct2]=y&1;
        y>>=1;
    }
    reverse(ax.begin()+1,ax.begin()+1+ct1);
    reverse(ay.begin()+1,ay.begin()+1+ct2);

    
    int res=3e18;
    //求得到一样的前缀的最小代价
	for(int i=1;i<=ct1 && i<=ct2;i++){
		if(ax[i]!=ay[i])break;
		res=min(res,dp[ct1-i][ct2-i]);
	}
    //求全变成0的最小代价
	for(int i=ct1;i<=70;i++)
		for(int j=ct2;j<=70;j++)
			res=min(res,dp[i][j]);
    
	cout<<res<<"\n";
}
signed main() {
    vcoistnt
    cout<<fixed<<setprecision(2);
    init();
    int _=1;
    cin>>_;
    while(_--) solve();
    return 0;
}


http://www.kler.cn/a/590991.html

相关文章:

  • OctoTools:一个具有复杂推理可扩展工具的智体框架
  • 人工智能混合编程实践:Python AgentOCR进行文本识别
  • LeetCode 2614.对角线上的质数:遍历(质数判断)
  • 三个线程按顺序交替打印 A B C
  • 【玩转正则表达式】Python、Go、Java正则表达式解释器的差异解析(附示例)
  • GitHub Copilot两期连看:开发流程全览及 Copilot 在 SQL 开发中的妙用
  • 【QT:多线程、锁】
  • OceanBase 读写分离最佳实践
  • MySQL原理:逻辑架构
  • 开源模型中的 Function Call 方案深度剖析
  • qwen2.5-vl复现日志
  • Certbot实现SSL免费证书自动续签(CentOS 7 + nginx/apache)
  • Python刷题:流程控制(上)
  • Pytest项目_day01(HTTP接口)
  • C++八大常见的设计模式的实现与实践指南
  • 服务器防火墙根据什么特征来过滤数据包?
  • H3C SecPath SysScan-AK 系列漏洞扫描系统
  • vue中根据html动态渲染内容
  • 设备物联网无线交互控制,ESP32无线联动方案,产品智能化响应
  • 基于SpringBoot的Mybatis和纯MyBatis项目搭建的区别