Codeforces Round #750 (Div. 2)简训

导语

日常

涉及的知识点

思维,字符串,数学,位运算,DP

链接:Codeforces Round #750 (Div. 2)简训

题目

A Luntik and Concerts

题目大意:有a首1分钟的歌,b首2分钟的歌,c首3分钟的歌,现在想把所有歌分成两个歌单,求出两个歌单之间的时间差最小值

思路:总时间和为 a + 2 b + 3 c a+2b+3c a+2b+3c,由于a,b,c的数量都大于等于1,这里有一个结论:a个1,b个2,c个3可以组成0–a+2b+3c中任意一个数,用贪心的策略即可证明,那么题目就简单了,如果总和是偶数,代表可以一分为二,否则差值最小为1

ps:为什么是这个结论,我不能接受,可恶

代码

#include <bits/stdc++.h>
using namespace std;
int t,a,b,c;
int main() {
    cin >>t;
    while(t--) {
        cin >>a>>b>>c;
        cout <<((a+b*2+c*3)&1?1:0)<<endl;
    }
    return 0;
}

B Luntik and Subsequences

题目大意:给出一个长度为n的非负整数序列,序列和为s,定义一个子序列为接近的当且仅当子序列和与s直接差值为1,求一共有多少个接近的子序列

思路:判断去掉1和0的方案即可

代码

#include <bits/stdc++.h>
using namespace std;
int t,n;
int main() {
    cin >>t;
    while(t--) {
        int one=0,zero=0;
        long long res=0;
        cin >>n;
        for(int i=0; i<n; i++) {
            int x;
            cin >>x;
            if(x==1)one++;
            if(x==0)zero++;
        }
        res=1ll*one*(1ll<<zero);
        cout <<res<<endl;
    }
    return 0;
}

C Grandma Capa Knits a Scarf

题目大意:给出一个只有小写字母的字符串,只能选择一个小写字母,然后删除字符串中任意个与该字母相等的字符使得最后的字符串为回文串,求出能构造出回文串的删除字符的最小值

思路:首先是每种小写字母都尝试一遍,假设当前已经选择的小写字母为 x x x,使用两个指针指向原字符串的首尾,比较首尾是否相同,如果相同各进一位,如果不同,判断是否有一位为 x x x,如果是则对应删除并进下一位,以此类推,如果到某一位置不能删除,说明该字母不行,尝试下一个

代码

#include <bits/stdc++.h>
using namespace std;
int t,n;
char str[121212];
int main() {
    cin >>t;
    while(t--) {
        cin >>n;
        cin >>str;
        int res=0x3f3f3f3f;
        for(char i='a'; i<='z'; i++) {
            int l=0,r=n-1,ans=0;
            while(l<=r) {
                if(str[l]==str[r])l++,r--;
                else if(str[l]==i) l++,ans++;//删除不对称的部分
                else if(str[r]==i)r--,ans++;//同上
                else {
                    ans=0x3f3f3f3f;//无穷大为非法值
                    break;
                }
            }
            res=min(ans,res);
        }
        cout <<(res==0x3f3f3f3f?-1:res)<<endl;
    }
    return 0;
}

D Vupsen, Pupsen and 0

题目大意:给出一个长度为n的无0的整数序列a,先构造一个相同长度的无0的整数序列b满足 ∑ i = 1 n a i b i = 0 \sum_{i=1}^na_ib_i=0 i=1naibi=0( ∑ i = 1 n b i < 1 0 9 \sum_{i=1}^nb_i\lt10^9 i=1nbi<109),求出这个b

思路:如果n为偶数,每两个相邻数设为一对,假设为 a i , a i + 1 a_i,a_{i+1} ai,ai+1,那么直接构造n/2个 − a i + 1 , a i -a_{i+1},a_i ai+1,ai即可,如果为奇数,把前三个拿出来,这三个数之中必定有两个之和不为0,假设为 a i , a j a_i,a_j ai,aj,另一个为 a k a_k ak,构造 − a k , − a k , a i + a j -a_k,-a_k,a_i+a_j ak,ak,ai+aj即可,如果选择的两个之和为0,显然不满足b的定义,其余的偶数个直接同第一种情况处理

代码

#include <bits/stdc++.h>
using namespace std;
int t,n,a[121212];
int main() {
    cin >>t;
    while(t--) {
        cin >>n;
        int start=1;
        for(int i=1; i<=n; i++)
            cin >>a[i];
        if(n&1) {//奇数直接抽前三个
            if(a[1]+a[2]!=0)
                cout <<-a[3]<<" "<<-a[3]<<" "<<a[1]+a[2]<<" ";
            else if(a[2]+a[3]!=0)
                cout <<a[2]+a[3]<<" "<<-a[1]<<" "<<-a[1]<<" ";
            else
                cout <<-a[2]<<" "<<a[1]+a[3]<<" "<<-a[2]<<" ";
            start=4;
        }
        for(int i=start; i<=n; i+=2)//两两相加
            cout <<-a[i+1]<<" "<<a[i]<<" ";
        cout <<endl;
    }
    return 0;
}

F1 Korney Korneevich and XOR (easy version)

题目大意:一个长为n的序列a,希望找到所有满足存在一个a的上升子序列其异或和等于x的非负整数x,现给出a,求出所有x

思路:序列中最大值为500,异或和的最大值不超过512,可以暴力枚举异或和,判断当前异或和是否可获得,记录对应的异或和值子序列的最后一个元素,之后更新,转移方程为 d p [ j ] = m i n ( d p [ j ⊕ a [ i ] ] , a [ i ] ) dp[j]=min(dp[j\oplus a[i]],a[i]) dp[j]=min(dp[ja[i]],a[i]),j为异或和值,a[i]为当前元素值

代码

#include <bits/stdc++.h>
using namespace std;
int t,n,dp[1000],a[121212];
int main() {
    cin >>n;
    memset(dp,0x3f,sizeof(dp));//初始化为无穷大
    for(int i=1; i<=n; i++)cin >>a[i];
    for(int i=1; i<=n; i++) {
        dp[a[i]]=min(dp[a[i]],a[i]);//首先只选自己是可以的
        for(int j=0; j<=512; j++)if(dp[j]<=a[i])dp[j^a[i]]=min(dp[j^a[i]],a[i]);
        //如果当前异或和为j,下一个元素大于异或序列的最后一个元素,代表序列可拓展,更新异或和对应的末元素
    }
    set<int>s;
    for(int i=0; i<=512; i++)if(dp[i]!=0x3f3f3f3f)s.insert(i);
    cout <<s.size()<<endl;
    for(auto i:s)cout <<i<<" ";
    cout <<endl;
    return 0;
}

参考文献

  1. Codeforces Round #750 (Div.2) Editorial
  2. F1 - Korney Korneevich and XOR (easy version)(暴力+简单DP)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值