IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> Codeforces Round #824 (Div. 2) 补题C、D -> 正文阅读

[C++知识库]Codeforces Round #824 (Div. 2) 补题C、D

Codeforces Round #824 (Div. 2) 补题C、D

B:Tea with Tangerines贪心Mid–

题意

有n块饼,可以通过一次操作将x大小的饼分成y、z两份。

问最少操作数,使得任意两块饼的大小严格小于两倍

思路

假设n块饼中最小的为a[0],最终最小的饼大小为min

那么为了达到最优解,不能分割a[0],不然所有的饼都要分割

于是 m i n ≤ a [ 0 ] 并且 2 ? m i n ? 1 ≤ a [ 0 ] min\leq a[0]并且2*min-1\leq a[0] mina[0]并且2?min?1a[0],为了让操作数尽可能小,选取min尽可能大,于是min=a[0],每次重其他饼中拆最多2*a[0]-1的饼

注意:

  1. 其他饼%(2*a[0]-1)==0时,那么操作数为其他饼/(2*a[0]-1)-1
  2. 其他饼%(2*a[0]-1)!=0时,那么操作数为其他饼/(2*a[0]-1),并且不用担心余数会小于min,因为拆出的饼大小为2*a[0]-1,那么a[0]-1+余数会大于等于min的

代码

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

int n;
ll a[1000];

int main(){
    int t;
    cin>>t;
    while(t--){
        cin>>n;
        for(int i=0;i<n;i++)cin>>a[i];
        sort(a,a+n);
        ll ans=0;
        // ll ans=0;
        // if(a[0]==1){
        //     for(int i=0;i<n;i++)ans+=a[i]-1;
        //     cout<<ans<<endl;
        //     continue;
        // }
        for(int i=1;i<n;i++){
            ans+=a[i]/(2*a[0]-1);
            if(a[i]%(2*a[0]-1)==0)ans--;
        }
        cout<<ans<<endl;
    }
}

C:Phase Shift模拟Mid

题意

我们可以把每个字符进行一个映射,但是要求这个映射关系是可以组成一个26个字母成环,给你一个字符串f,问最后能得到的映射的最小字典序的字符串s,其中s[i]->f[i]

思路

为了得到最小字典序,优先选择为出现的小字符进行映射。

但是注意防止提前出现成环现象,因为这样就不能形成一个26个字母环。

可以通过遍历一遍已形成的映射关系判断是否成环,但是还得注意最终26个字母可以可以成环,要进行特判

代码

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

map<char,char>m;

bool check(char j,char k){
    int num=0;
    while(m[j]){
        if(m[j]==k)return true;
        j=m[j];
        num++;
        if(num==24)return false;
    }
    return false;
}

int main(){
    int t;
    cin>>t;
    while(t--){
        int n;
        string s,out="";
        cin>>n>>s;
        m.clear();
        map<char,int>vis;
        for(char i='a';i<='z';i++)vis[i]=0;
        for(int i=0;i<s.length();i++){
            if(m[s[i]]){
                out+=m[s[i]];
                continue;
            }
            for(char j='a';j<='z';j++){
                if(vis[j]||s[i]==j)continue;
                if(check(j,s[i]))continue;
                vis[j]=1;
                m[s[i]]=j;
                out+=j;
                break;
            }
        }
        cout<<out<<endl;
    }
}

D:Meta-set状态压缩+思维Hard–

题意

张卡片都有k个元素,每个元素的赋值只可能是0,1,2,三张卡如果每个元素要么相同要么都不同的时候,我们就说这三张卡是一组good,我们说五张卡中如果能选出至少两组good,那么这五张卡被称为一队,问有几队。

思路

  • 先考虑

    • 若三张卡属于一组,那么他们每个元素要么全相同、要么全相异。而元素可取的值只有3种,那么可以得出任意两张卡可以唯一确定第三张卡,使三张卡属于一组
    • 由于元素可以取值为0、1、2,而且元素最多为20个。可以利用3进制状态压缩,将每一张卡压缩为一个数,那么这个数就与这张卡一一对应形成映射,这样就方便判断某张卡是否在集合中
    • 暴力枚举两张卡,确定第三张卡是否在集合中,如果在那么它们可以组成一组。记录下可以组成的组数。
  • 再考虑

    • 每一队只有5张卡,而且每一队要求至少有两组:

      • 组与组之间不可能共用3张卡,否则其为1组
      • 组与组之间不可能共用2张卡,因为两张卡唯一确定第三张卡,情况与上述相同
      • 组与组之间只能共用1张卡,这样才满足一队5张卡且至少有两组

      于是:每一队只能有两组且两组共用一张卡

    • 为了计算队数,可以分别计算每张卡所属的组的组数x,那么该张卡对队数的贡献为C(x,2);

代码

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

const int N=1e3+5,K=30;
int a[N][K];
int n,k;
ll three[K];
map<ll,int>ma;
map<int,int >se;
set<vector<int> >sett;


 void solve(){
    three[0]=1;
    for(int i=1;i<=k;i++)three[i]=three[i-1]*3;
    for(int i=0;i<n;i++){
        ll ans=0;
        for(int j=0;j<k;j++){
            cin>>a[i][j];
            ans+=a[i][j]*three[j];
        }
        ma[ans]=i;
    }
    for(int i=0;i<n;i++){
        for(int j=i+1;j<n;j++){
            ll ans=0;
            for(int w=0;w<k;w++){
                if(a[i][w]==a[j][w])ans+=a[i][w]*three[w];
                else{
                    map<int,int>m;
                    m[a[i][w]]=1;
                    m[a[j][w]]=1;
                    if(!m[0])ans+=0;
                    else if(!m[1])ans+=1*three[w];
                    else if(!m[2])ans+=2*three[w];
                }
            }
            if(ma.find(ans)!=ma.end()){
                vector<int>v;
                v.push_back(i);
                v.push_back(j);
                v.push_back(ma[ans]);
                sort(v.begin(),v.end());
                sett.insert(v);
            }
        }
    }
    for(set<vector<int> >::iterator it=sett.begin();it!=sett.end();it++){
        se[(*it)[0]]++;
        se[(*it)[1]]++;
        se[(*it)[2]]++;
    }
    ll ans=0;
    for(map<int,int >::iterator it=se.begin();it!=se.end();it++){
        ll y=it->second;
        ans+=(y*(y-1))/2;
    }
    cout<<ans<<endl;
 }


int main(){
    cin>>n>>k;
    solve();
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-10-08 20:22:12  更:2022-10-08 20:25:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 4:47:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码