Codeforces Round #808 (Div. 2) A,B

A

题目大意:

  • 给定一个具有n (2 ≤ n ≤ 100) 个元素的数组
  • 对这个数组每次可以使得 a[i] = a[i] - a[i - 1] (2 ≤ i ≤ n)
  • 问对于这个给定的数组,是否可以通过操作使得a[i] = 0 (2 ≤ i ≤ n)

解法:

  1. 首先从下标为2的元素开始看,a[2]如果最后需要通过减去a[1]变成0,那么a[2] % a[1] == 0 && a[1] < a[2],是必须成立的。
  2. 然后下标为3的元素,因为a[1] < a[2] 所以把a[2]变成a[1],可以有更大的可能使得后面的数变成0,那么a[3] % a[1] == 0,也应该成立。

依次类推,条件就是 a[i] % a[1] == 0 (2 ≤ i ≤ n)

#include <iostream>

using namespace std;

const int N = 110;
int a[N];

int main()
{
    int t;
    cin >> t;
    while(t --)
    {
        int n;
        cin >> n;
        for(int i = 1;i <= n;i ++) cin >> a[i];
        int flag = 0;
        for(int i = 2;i <= n;i ++) if(a[i] % a[1] != 0) 
        {
            flag = 1;
            break;
        }
        if(flag) puts("NO");
        else puts("YES");
    }
    return 0;
}

B

题目大意:

  • 给定三个数n, l , r (1 ≤ n ≤ 1e5, 1≤ l ≤ r ≤ 1e9).
  • 构造一个具有n个元素的数组,使得 gcd(i, a[i]) 各不相同,其中a[i]属于[l, r]这个区间

解法:

  1. 当i = 1,a[i]的值无论为什么gcd(i, a[i]) == 1
  2. 当i = 2,首先gcd(i, a[i])不能为1,那么gcd(i, a[i]) 一定为2
  3. 当i = 3,gcd(i, a[i]) != 1 && gcd(i, a[i]) != 2,那么gcd(i, a[i]) 一定为3

以此类推,可以知道所有位置上的数,都是其下标的倍数
那么问题就可以进行简化,现在问题就是判断对于每一个下标,它的某一个倍数是否在[l, r]区间内。

  1. 当i > r, 那么就不存在
  2. 当l <= i <= r,那么就直接选i
  3. 当i < l,首先判断 l 是否是 i 的倍数,如果不是就利用 l + i - l % i ,求得大于 l 的最小的 i 的倍数,然后判断这个数是否大于了r。
#include <iostream>
#include <map>
#include <vector>

using namespace std;

int main()
{
    int t;
    cin >> t;
    while(t --)
    {
        int n, l, r;
        cin >> n >> l >> r;
        vector<int> res;
        for(int i = 2;i <= n;i ++)
        {
            if(i > r) continue;
            else if(l <= i) res.push_back(i);
            else if(l % i == 0) res.push_back(l);
            else if((l + (i - l % i)) <= r) res.push_back(l + (i - l % i));
        }
        if(res.size() < n - 1) puts("NO");
        else 
        {
            puts("YES");
            cout << l << " ";
            for(int i = 0;i < res.size();i ++) cout << res[i] << " ";
            cout << endl;
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值