2020 11.11 做题记录

2020 11.11 做题记录

第一题:codeforces1445C Division

链接:

https://codeforces.com/contest/1445/problem/C

原题:

Oleg’s favorite subjects are History and Math, and his favorite branch of mathematics is division.
To improve his division skills, Oleg came up with 𝑡 pairs of integers 𝑝𝑖 and 𝑞𝑖 and for each pair decided to find the greatest integer 𝑥𝑖, such that:
𝑝𝑖 is divisible by 𝑥𝑖;
𝑥𝑖 is not divisible by 𝑞𝑖.
Oleg is really good at division and managed to find all the answers quickly, how about you?
Input
The first line contains an integer 𝑡 (1≤𝑡≤50) — the number of pairs.
Each of the following 𝑡 lines contains two integers 𝑝𝑖 and 𝑞𝑖 (1≤𝑝𝑖≤1018; 2≤𝑞𝑖≤109) — the 𝑖-th pair of integers.
Output
Print 𝑡 integers: the 𝑖-th integer is the largest 𝑥𝑖 such that 𝑝𝑖 is divisible by 𝑥𝑖, but 𝑥𝑖 is not divisible by 𝑞𝑖.

One can show that there is always at least one value of 𝑥𝑖 satisfying the divisibility conditions for the given constraints.
Example
input

3
10 4
12 6 
179 822

output

10
4
179

题目大意:

输入两个数p,q,找到满足以下条件的最大的数x:

  1. x能整除p
  2. x不能被q整除

思路:

我们分为两个情况讨论:

  1. q不可以整除p时:
    很显然,x的值就是p
  2. q可以整除p时:
    遍历一下q的因数,则这个因数一定也是p的因数,如果这个因数不为1,则先从p开始每次除以一个这个因数,直至不被q整除。每次更新最大值。

AC代码

#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = a; i <= b; i++)
#define dow(i, a, b) for(int i = a; i >= b; i--)
#define pi acos(-1)
#define ll unsigned long long 
#define db double
#define maxn 55
void io(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}
void solve(){
    ll p, q;
    ll aws = 0;
    cin >> p >> q;
    if(p % q) {
        cout << p << endl;
        return;
    }
    for(ll i = 1; i * i <= q; i++){
        if(q % i) continue;
        ll t = p;
        if(i != 1){
            while(t % q == 0) t /= i;
            aws = max(aws, t);
        }
        t = p;
        while(t % q == 0) t /= (q / i);
        aws = max(aws, t);
    }
    cout << aws << endl;
}
int main(){
    io();
    int t;
    cin >> t;
    while(t--){
        solve();
    }
}

第二题:codeforces1443D Extreme Subtraction

链接:

https://codeforces.com/contest/1443/problem/D

原题:

You are given an array 𝑎 of 𝑛 positive integers.

You can use the following operation as many times as you like: select any integer 1≤𝑘≤𝑛 and do one of two things:

  • decrement by one 𝑘 of the first elements of the array.

  • decrement by one 𝑘 of the last elements of the array.
    For example, if 𝑛=5 and 𝑎=3,2,2,1,4, then you can apply one of the following operations to it (not all possible options are listed below):

  • decrement from the first two elements of the array. After this operation 𝑎=2,1,2,1,4;

  • decrement from the last three elements of the array. After this operation 𝑎=3,2,1,0,3;

  • decrement from the first five elements of the array. After this operation 𝑎=2,1,1,0,3;
    Determine if it is possible to make all the elements of the array equal to zero by applying a certain number of operations.

Input
The first line contains one positive integer 𝑡 (1≤𝑡≤30000) — the number of test cases. Then 𝑡 test cases follow.

Each test case begins with a line containing one integer 𝑛 (1≤𝑛≤30000) — the number of elements in the array.

The second line of each test case contains 𝑛 integers 𝑎1…𝑎𝑛 (1≤𝑎𝑖≤106).

The sum of 𝑛 over all test cases does not exceed 30000.

Output
For each test case, output on a separate line:

YES, if it is possible to make all elements of the array equal to zero by applying a certain number of operations.
NO, otherwise.
The letters in the words YES and NO can be outputed in any case.
input:

4
3
1 2 1
5
11 7 9 6 8
5
1 3 1 3 1
4
5 2 1 10

Output:

YES
YES
NO
YES

题目大意:

给出一段长为n的数组,有两种操作,从头开始若干个数同减,和从尾部开始连续若干个数同减,问你是否可以把这n个数全部变为0

思路:

我当时时候脑子一片空白,就随手去找一找性质,突然就发现有一下的性质:假设第i位的数字为ai,从左开始删除的数的和为xi,从右开始删除的数字的和为yi,那么有一下三条式子约束:

  • xi + yi = ai
  • xi <= xi-1
  • yi >= yi-1
    经过推导后我们就能得到xi的式子:
  • xi <= ai
  • xi <= xi-1
  • xi <= ai - ai-1 + xi
    很显然我们就会发现xi一定是递减的,那么最好的情况就是让xi=ai,然后向后更新,如果小于零了就代表这个数组不能全部变为0

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = a; i <= b; i++)
#define dow(i, a, b) for(int i = a; i >= b; i--)
#define db double
#define ll long long
#define pi acos(-1)
#define maxn 100005
void io(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}
int f[maxn];
void solve(){
    int n;
    cin >> n;
    rep(i, 1, n) cin >> f[i];
    ll aws = 0;
    dow(i, 30, 0){
        int cnt = 0;  
        rep(j, 1, n){
            if(f[j] >= (1 << i) && f[j] < (1 << (i + 1))){
                cnt++;
            }
        }
        aws += cnt * (cnt - 1) / 2;
    }
    cout << aws << endl;
}
int main(){
    int t;
    cin >> t;
    while(t--){
        solve();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值