Codeforces Round #696 (Div. 2)A. Puzzle From the Future

A题 Puzzle From the Future

题目链接https://codeforces.com/contest/1474/problem/A

题意:

给出一个二进制数a,找出另一个二进制数b,使之按位以十进制的格式相加得到的c数值最大,且c没有连续相同的两位。(就是把两个只含0, 1的十进制数相加得到没有相同两位的最大数,比如a(2) = 1001,b(2) 就应该为1101,得到的c(10)为2102 )

思路:

知道题意之后就很好发现,如果a, b只由0, 1组成,那么其相加的结果c中只可能出现0,1,2三个数。

由于c相邻的两位不同,且要是最大值,不论a的首位是什么,b的首位必然是1才会使c的值最大。那么对于b的其他位,我们只需要先记录前一位c的值pre:
如果pre = 2,那c i 只能为1才能使c最大,这就取决于a i的值了,如果a i = 1, 那么b i = 0,如果a i = 0,那么b i = 1,也就是b i = a i - 1;

如果pre = 1,那 c i 可能为0,可能为2:如果a i = 1, 那b i = 1;如果a i = 0,那么b i = 0,也就是说a i = b i

如果pre = 0,那么c i可能为1, 2,那么当a i = 1,b i = 1,a i = 0, b i = 1,也就是b i恒等于1.

ci = 2
ci = 1
ci = 2
ci = 0
ci = 1
ci = 1
pre =
0
ai = 1
bi = 1
bi = 1
ai = 0
bi = 1
1
ai = 1
bi = 1
bi = ai
ai = 0
bi = 0
2
ai = 1
bi = 0
bi=1-ai
ai = 0
bi = 1

AC代码

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn = 1e5 + 100;
int le[maxn];

int main(){
    ios::sync_with_stdio(0);
    cin.tie(); cout.tie(0);

    int t; cin >> t;
    while(t--){
        int n; cin >> n;
        string s; cin >> s;
        int pre = s[0] - '0' + 1;
        cout << 1;
        for(int i = 1; i < s.length(); i ++){
            if(pre == 2){
                pre = 1;
                cout << pre - (s[i] - '0');
            }
            else if(pre == 1){
                pre = 2 * (s[i] - '0');
                cout << s[i] - '0';
            }
            else {
                cout << 1;
                pre = s[i] - '0' + 1;
            }
        }
        cout << "\n";
    }
    return 0;
}

B Different Divisors

题目链接https://codeforces.com/contest/1474/problem/B

题意:

计算出一个值a,使得a至少存在4个因子,且任意两个因子之间的差值大于等于给定的整数b,且a是在满足这个条件下的最小值。

思路:

先看示例
当b为1时,a的最小值为6(6的因子为:1,2,3,6);
当b为2时,a的最小值为15(15的因子为:1,3,5,15);

哦吼吼你是不是想到了a = (b + 1)* (b + b + 1);但是你试试b = 3?是不是就变成4 * 7 = 28,因子就变成了1,2,4,7,28了,就不满足任意两个因子的差值至少为b了。

再想以下,除了1以外,任意一个数都有两个因子:1和本身,那要找至少有四个因子的数的最小值,就找刚刚好只有四个因子的肯定比多于四个的要优,所以上面就用的是两个数相乘,那么我们只需要找到这两个数就行了。而上式出现的问题就是,b + 1或者b + b + 1可能是合数,导致求出的a的因字数大于4个且,由于多出的因子是本有的因子的因子,所以导致了任意两个因子之间不满足差值最小为b(因为本来b + 1就是踩线擦边球了,b + 1 再变成 b + 1 = c * d(c,d都不为1)的话,那abs(c - d) 肯定就小于b了呀)。所以就容易推出剩余的两个因子是素数(观察样例也发现是的),找出最小的,且>= b + 1的素数,就是二个因数,那第三个因数是不是就是>= b + b + 1的最小素数呢?不一定哦,万一第二个素数就刚好>= b + b + 1了呀,所以第三个因子应该是大于第二个因子的最小素数。

在本题中,由于b的范围很小,所以直接暴力求素数就可以了。

那么答案就是第二、三个因子的乘积就是了。因为res = 因子 2 * 因子 3,那么res 的因子就又四个,分别为1,因子 2,因子 3,res。

AC代码

#include <bits/stdc++.h>
 
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 100;
int le[maxn];
 
bool isPrime(int a){
    for(int i = 2; i <= sqrt(a); i ++){
        if(a % i == 0) return false;
    }
    return true;
}
 
int main(){
    ios::sync_with_stdio(0);
    cin.tie(); cout.tie(0);
 
    int t; cin >> t;
    while(t--){
        int d; cin >> d;
        int a = 1 + d, b = 1 + 2 * d;
        while(!isPrime(a)) a ++;
        b = a + d;
        while(!isPrime(b)) b ++;
        cout << 1ll * a * b << "\n";
    }
    return 0;
}

C Array Destruction

题目链接https://codeforces.com/contest/1474/problem/C

题意:

给出一个长度为2n的数组,判断数组内的任意三个数是否满足a + b = c,若满足,删除a,b;再判断数组内是否存在另外的两个数是否满足d + e = max(a, b),若满足,就删除d,e;一直循环做这个操作,直到数组内的数字被删除完毕为止并输出最初的c和之后两个数的组合即(a, b);(c, d)…(最初提到的c就是第一组a, b的和而已)

所以这个题就和明确了,每次找到当前数组的最大值,然后找到一个值与之匹配相加,如果其和等于上一个匹配的最大值,则继续匹配,一直匹配到数组

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值