Codeforces Round 1069 (Div. 2)

A. Little Fairy's Painting

ideas:

我感觉题目一点都不好读懂

题目的意思是:要去填充1e181e^{18}1e18个格子,有无限种颜色,给出n个,找规律去填充后面的。

比如案例三:
58 10 15 20 25 5 \\ 8\ 10\ 15\ 20\ 25 \\ 58 10 15 20 25

第0个位置的颜色数是8,第一个是10,这样不同的颜色数就是2,每一个数代表不同的颜色,这个案例中就是有5个不同颜色的数。此时第n+1位就填5,此时不同颜色数增加到6(因为5不再原来的数组中)。

后续填充的规则是:不同颜色数作为颜色编号。

那么当,不同颜色数等于前n位颜色编号中的某一位时,不同颜色数就不再增加,答案也就因此固定。

code:

cpp 复制代码
    int n;
    cin>>n;
    set<int>st;
    for(int i=0;i<n;i++){
        cin>>a[i];
        st.insert(a[i]);
    }
    int k=st.size();
    int ans=INT_MAX;
    for(int i=0;i<n;i++){
        if(a[i]>=k)
            ans=min(ans,a[i]);
    }
    cout<<ans<<endl;

B. XOR Array

ideas:

题目含义是:

1.在l−rl-rl−r这个区间内的XOR 的结果为0;

2.在l−rl-rl−r这个区间外的XOR 的结果不为0。
结论:
al⊕al+1⊕...⊕ar=prer⊕prel−1al ⊕ al+1 ⊕ ... ⊕ ar = prer ⊕ prel-1al⊕al+1⊕...⊕ar=prer⊕prel−1

推导:
a1⊕a2⊕a3....⊕al....⊕ar=prera_1\oplus a_2 \oplus a_3.... \oplus a_l.... \oplus a_r = prera1⊕a2⊕a3....⊕al....⊕ar=prer
a1⊕a2⊕a3....⊕al=prela_1\oplus a_2 \oplus a_3.... \oplus a_l = prela1⊕a2⊕a3....⊕al=prel

根据异或的性质:
a⊕a=0a\oplus a = 0a⊕a=0

很轻易得出上面的结论。

要想到答案为0,得出:
prer=prel−1prer = prel-1prer=prel−1

于是我们可以得出构造方法:

1.只需要prer=prel−1prer = prel-1prer=prel−1

2.其他位置的任意,我们选择prei=iprei=iprei=i

3.我们构造的aiaiai数组是前缀异或值,反解计算出每一位的值。

code:

cpp 复制代码
    int n,l,r;
    cin>>n>>l>>r;
    vector<int>pre(n+2);
    for(int i=0;i<n+2;i++)pre[i]=i;
    pre[l-1]=pre[r];
    for(int i=0;i<n;i++){
        cout<<(pre[i]^pre[i+1])<<" ";
    }
    cout<<endl;

C. Needle in a Haystack

ideas:

一个模拟题。

思路是:

1.可行性检查:

如果长度一样,一个字符t中没有就输出"Impossible"

如果有一个字符的次数,t中不够,就输出"Impossible"

2.分离字符:

把s中的每一个字符分离出来,剩下的字符串排序

3.合并字符:

对于每一个s中的字符,找到合适的位置放进去就可以

最后把剩余的字符加进去。

code:

cpp 复制代码
    string s,t;
    cin>>s>>t;
    map<char,int>mpa,mpb;
    for(auto c:s)mpa[c]++;
    for(auto c:t)mpb[c]++;

    //可行性检查
    for(auto c:s){
        if(mpb[c]<mpa[c]){
            cout<<"Impossible"<<endl;
            return ;
        }
    }

    //分离字符
    string tmp="";
    for(char c='a';c<='z';c++){
        int d=mpb[c]-mpa[c];
        tmp+=string(d,c);
    }
    sort(tmp.begin(),tmp.end());

    //合并字符
    string ans="";
    int pos=0;
    for(auto c:s){
        while(pos<tmp.size()&&tmp[pos]<c){
            ans+=tmp[pos];
            pos++;
        }
        ans+=c;
    }

    while(pos<tmp.size()){
        ans+=tmp[pos];
        pos++;
    }
    cout<<ans<<endl;
相关推荐
YLCHUP27 分钟前
【思维&图论建模】题解:债权(debt)_图论_建模_思路转化_思维题目_C++算法竞赛
c++·笔记·算法·数学建模·贪心算法·深度优先·图论
思麟呀1 小时前
背包DP(01背包+完全背包)
c++·算法
笑容掩饰我的失落2 小时前
区块链从小白到精通(七):Solidity 语法精讲——数据类型、函数、修饰器与事件
算法·区块链·php·智能合约·哈希算法
Pniubi3 小时前
力扣24. 两两交换链表中的节点(递归)
算法·leetcode·链表
꧁细听勿语情꧂4 小时前
直接选择排序,堆排序,冒泡排序,递归快速排序、hoare版本、挖坑法、lomuto前后指针,非递归快速排序
c语言·开发语言·数据结构·算法
俊俊几年的4 小时前
动态规划(Dynamic Programming)详解:从入门到 LeetCode Hot 100
linux·c++·算法·leetcode·嵌入式·动态规划·c
小雉系统13 小时前
BcoreOS安全通信架构:FsSession 抗算法后门安全设计
算法·安全·架构
唐墨12317 小时前
linux kernel 比较数据大小的宏定义
linux·算法
拂拉氏18 小时前
【知识讲解-题目讲解】 统计满足K约束的子字符串数量2 (滑动窗口+前缀和+二分查找+分析)
算法·前缀和·二分查找·滑动窗口