CodeTON Round 1 (Div. 1 + Div. 2, Rated, Prizes)

A - Good Pairs

题意

找一个数对满足题目所给的公式

输出下标

题解

输出最大值和最小值的下标就行了,因为本质上就是这个点到两端的距离之和

Code

int T;
int n;
PII a[N];

void solve(){
    cin >> n;
    for (int i = 1; i <= n; i++){
        cin >> a[i].x;
        a[i].y = i;
    }

    sort(a + 1, a + 1 + n);

    cout << a[1].y << ' ' << a[n].y << endl;
}

B - Subtract Operation

题意

每次选择一个数对全体数组的数来相减,问最后剩一个数能不能时k

题解

本质上,每次操作过后两个数的相对大小关系是不会改变的。

所以说,最后剩的两个数是多少,与他们最初的差是一样的

所以对于每一个数检查一下有没有与之对应的数使得两者相加为k

Code

int T;
ll n, k;
int a[N];

void solve(){
    cin >> n >> k;
    // ll summ = 0;
    map<ll, int> m;
    int maxx = 0;
    for (int i = 1; i <= n; i++){
        cin >> a[i];
        maxx = max(a[i], maxx);
        m[a[i]]++;
    }

    for (ll i = 1; i <= n; i++){
        if(m[a[i] + k]){
            cout << "YES" << endl;
            re;
        }
    }
        cout << "NO" << endl;
}

C - Make Equal With Mod

题意

给定数组,可以选取一个数 2 ≤ k 2\leq k 2k使得,将数组中的所有元素变为 a i % k a_i \%k ai%k

若干操作后,使得数组各元素相等

题解

因为操作可以无限次,那么我们最开始的想法不妨设最后都变成0

那不就都除以这个数本身就完了吗

但是题目要求 2 ≤ k 2\leq k 2k,如果数组中出现了1的话,那么肯定是不能除以自己的,而要满足题意,那必须得是让所有的数变成1,也就是 mod 上他自己减一,就可以让他们全部都变成1了

但是如果数组中出现了两个数相差为1的情况,这时候按照上面的方法就会出现0了,之后就不会再相等了

而当数组出现了0,那么还是遵循上面第一条的情况就可以了

如果数组中出现了0和1,就符合第二种说的情况

Code

int T;
int n;
int a[N];

void solve(){
    int one = 0;
    int ok = 1;

    cin >> n;
    for (int i = 1; i <= n; i++){
        cin >> a[i];
        if(a[i] == 1)
            one = 1;
        if(i > 1 && a[i - 1] != a[i])
            ok = 0;
    }

    if(ok){
        cout << "YES" << endl;
        re;
    }

    if(one){
        sort(a + 1, a + 1 + n);
        for (int i = 2; i <= n; i++){
            if(a[i] - a[i - 1] == 1){
                cout << "NO" << endl;
                re;
            }
        }
        cout << "YES" << endl;
        re;
    }
    else cout << "YES" << Endl;
}

D - K-good

题意

给你一个数n,问能不能拆成k个数的和使这k个数模k的结果都相同

输出这个k

题解

假设我们现在n已经被拆成了k个数,即
a 1 + a 2 + a 3 + ⋯ + a k = n a_1+a_2+a_3+\cdots+a_k=n a1+a2+a3++ak=n
而这些数%k都不相同,而且有k个,那么显然这些数一定都是 0 ∼ k − 1 0 \sim k-1 0k1之间的,那么
n = k ∗ ( k − 1 ) 2 + t k n = k 2 − k + 2 t k 2 n = k 2 ∗ ( k − 1 + 2 t ) n = k ∗ ( k − 1 + 2 t ) 2 n=\frac{k*(k-1)}{2}+tk \\ n=\frac{k^2-k+2tk}{2} \\ n=\frac{k}{2}*(k-1+2t) \\ n=k*\frac{(k-1+2t)}{2} n=2k(k1)+tkn=2k2k+2tkn=2k(k1+2t)n=k2(k1+2t)
若k为奇数,则 k − 1 + 2 t k-1+2t k1+2t为偶数;若k为偶数,则 k − 1 + 2 t k-1+2t k1+2t为奇数

即无论怎样,2n必定为一寄一偶相乘得到的

那么我们可以把这个偶数求出来,当2n不能再被2整除的时候,奇数也就出来了

需要注意的是n构造的式子中,已经减了一个2的质因子

最后输出的最小值是因为等式成立的话,k+2t-1一定是大于k的,所以输出最小

Code

ll n;

void solve(){
    cin >> n;
    ll tmp = n;
    int cnt = 1;
    while(tmp % 2 == 0)
        tmp /= 2, cnt++;
    if(tmp == 1) // 不满足一寄一偶
        cout << -1 << endl;
    else{
        cout << min(tmp, 1ll << (cnt)) << endl;
    }
    cout << endl;
}

E - Equal Tree Sums

参考https://www.zhihu.com/people/pzr-84

void dfs(int u, int fa){
    if(fa != -1)
        col[u] = !col[fa];
    else
        col[u] = 1;

    for(auto v: g[u]){
        if(v != fa && !col[v]){
            dfs(v, u);
        }
    }
}

void solve(){
    cin >> n;
    for (int i = 1; i <= n; i++){
        d[i] = col[i] = 0;
        g[i].clear();
    }

    for (int i = 1; i < n; i++){
        int a, b;
        cin >> a >> b;
        d[a]++;
        d[b]++;
        g[a].pb(b);
        g[b].pb(a);
    }

    dfs(1, -1);

    for (int i = 1; i <= n; i++){
        if(col[i])
            cout << -d[i] << ' ';
        else
            cout << d[i] << ' ';
    }
    cout << endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值