Codeforces Round #756(div3)A-D、F题解

Codeforces Round #756(div3) (A-D、F题解)

A:Make Even

签到

代码:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<stack>
    #include<queue>
    #include<string>
    #include<map>
    #include<set>
    #include<cmath>
    #include<algorithm>
    #define ll long long
    #define ld long double
    #define int long long
    #define rep(i, a, b) for(int i = a; i <= b; i++)
    #define _rep(i, a, b) for(int i = a; i >= b; i --)
    #define io std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
     
    using namespace std;
    const int N = 1e6 + 5;
     
    int n, a;
     
    signed  main(){
        cin >> n;
        while(n --){
            cin >> a;
            if(a % 2 == 0){
                cout << 0 <<endl;
                continue;
            }
            int flag = 0;
            while(a >= 10){
                if(a % 2 == 0)
                    flag = 1;
                a /= 10;
            }
            if(a % 2 == 0){
                cout << 1 << endl;
                continue;
            }
            if(flag){
                cout << 2 << endl;
                continue;
            }
            cout << -1 << endl;
     
        }
        return 0;
    }

B: Team Composition: Programmers and Mathematicians

签到

代码:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<stack>
    #include<queue>
    #include<string>
    #include<map>
    #include<set>
    #include<cmath>
    #include<algorithm>
    #define ll long long
    #define ld long double
    #define int long long
    #define rep(i, a, b) for(int i = a; i <= b; i++)
    #define _rep(i, a, b) for(int i = a; i >= b; i --)
    #define io std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
     
    using namespace std;
    const int N = 1e6 + 5;
     
    int n, a, b, ans;
     
    signed  main(){
        cin >> n;
        while(n --){
            cin >> a >> b;
            ans = (a + b) / 4;
            int t = min(a,b);
            ans = min(ans, t);
            cout << ans << endl;
        }
        return 0;
    }

C: Polycarp Recovers the Permutation

题目大意:对于一个数组a,选择它的最左或最右的最小值,加到b数组的最左或最右端。现给你b数组,求原来的a数组,如果无法构建出来输出-1。

思路:-1的情况很容易想到,就是整个数组最大值不在两端,剩下的直接模拟就行了。赛后又想了想,直接反转就行了。。。思维还是不行hhh。

代码:

    //模拟:
	#include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<stack>
    #include<queue>
    #include<string>
    #include<map>
    #include<set>
    #include<cmath>
    #include<algorithm>
    #define ld long double
    #define int long long
    #define rep(i, a, b) for(int i = a; i <= b; i++)
    #define _rep(i, a, b) for(int i = a; i >= b; i --)
    #define io std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
     
    using namespace std;
    const int N = 2e5 + 5;
    int a[N], ans[N*2];
    int n, t;
     
    signed  main(){
        cin >> t;
        while(t --){
            cin >> n;
            int m = 0;
            for(int i = 0; i < n; i ++)
                cin >> a[i], m = max(m, a[i]);
            int mx = max(a[0], a[n - 1]);
            if(m != mx){
                cout << -1 << endl;
                continue;
            }
            int idl = n, idr = n + 1, l = 0, r = n - 1;
            while(l < r){
                if(a[l] <= a[r])
                    ans[idl--] = a[l++];
                else
                    ans[idr++] = a[r--];
            }
            for(int i = idl + 1; i < idr; i++)
                cout << ans[i] << " ";
            cout << a[l] << endl;
        }
        return 0;
    }
	//规律:
	#include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<stack>
    #include<queue>
    #include<string>
    #include<map>
    #include<set>
    #include<cmath>
    #include<algorithm>
    #define ld long double
    #define int long long
    #define rep(i, a, b) for(int i = a; i <= b; i++)
    #define _rep(i, a, b) for(int i = a; i >= b; i --)
    #define io std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)

    using namespace std;
    const int N = 2e5 + 5;
    int a[N], ans[N*2];
    int n, t;

    signed  main(){
        cin >> t;
        while(t --){
            cin >> n;
            int m = 0;
            for(int i = 0; i < n; i ++)
                cin >> a[i], m = max(m, a[i]);
            int mx = max(a[0], a[n - 1]);
            if(m != mx){
                cout << -1 << endl;
                continue;
            }
            if(a[0] == mx){
                for(int i = n - 1; i > 0; i--)
                    cout << a[i] << " ";
                cout << mx << endl;
            }
            else{
                for(int i = n - 2; i >= 0; i --)
                    cout << a[i] << " ";
                cout << mx <<endl;
            }
        }
        return 0;
    }

D: Weights Assignment For Tree Edges

题目大意:给你两个数组a,p,a数组a[i]指i的父亲节点是a[i],当i跟a[i]相等的时候,i就是根节点,而对于每个点到根节点都有一个距离,这些距离关系的排序就是p数组,让你构造出一组点到根节点的距离,满足ap两个数组。

思路:对于每个节点加上一个rank值,再根据p数组来遍历赋值,使得p[i]节点到根节点的距离就是i,子节点自然只需要用i-父亲节点的rank值即可,-1的情况就是父亲的rank值比儿子的tank值更大。题目读懂了思路自然就出来了这道题就很简单了。

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<stack>
#include<queue>
#include<string>
#include<map>
#include<set>
#include<cmath>
#include<algorithm>
#define ll long long
#define ld long double
#define int long long
#define rep(i, a, b) for(int i = a; i < b; i++)
#define _rep(i, a, b) for(int i = a; i >=b; i --)
#define io std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)

using namespace std;
const int N = 200005;
int a[N], p[N], ans[N], r[N];
int n, t, f;

signed  main(){
    cin >> t;
    while(t --){
        bool ok = true;
        cin >> n;
        for(int i = 1; i <= n; i ++){
                cin >> a[i];
                if(a[i] == i)
                    f = i;
        }
        for(int i = 1; i <= n; i ++) cin >> p[i];
        if(p[1] != f)
            ok = false;
        for(int i = 1; i <= n; i ++)
            r[p[i]] = i;
        ans[f] = 0;
        for(int i = 2; i <= n && ok; i ++)
            if(i < r[a[p[i]]])
                ok = false;
            else
                ans[p[i]] = i - r[a[p[i]]];
        if(ok == false)
        {
            cout << -1 << endl;
            continue;
        }
        for(int i = 1; i <= n; i ++)
                cout << ans[i] << " ";
        cout <<endl;
    }
    return 0;
}

F: ATM and Students

题目大意:给你一个长度为n的数组以及一个缓冲值s,求其最长的单调区间+s严格非负,若有输出左右端,若无输出-1。(严格单调是指这个区间从l开始,一直到r和都是非负才行,所以前缀和可能行不通)。

思路:双指针直接找最大区间即可(权值线段树的做法应该也可以过,没试过只有个想法)。

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<stack>
#include<queue>
#include<string>
#include<map>
#include<set>
#include<cmath>
#include<algorithm>
#define ld long double
#define int long long
#define rep(i, a, b) for(int i = a; i < b; i++)
#define _rep(i, a, b) for(int i = a; i >=b; i --)
#define io std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)

using namespace std;
const int N = 2e5 + 5;

int n, t, s;
int a[N];

signed  main(){
    cin >> t;
    while(t --){
        cin >> n >> s;
        for(int i = 0; i < n; i ++)
            cin >> a[i];
        int l = 0, r = 0, sum = 0, ans = 0, ll, rr, cnt = 0, mx = 0;
        while(r < n && l < n){
            if(sum + s + a[r] >= 0)  sum += a[r], r++, cnt++;
            else if(sum + s + a[r] <= 0 && l == r)l++, r++;
            else{
                sum -= a[l];
                l++;
                cnt--;
            }
            if(mx < cnt){
                mx = cnt;
                ll = l;
                rr = r;
            }
        }
        if(mx)
            cout <<  ll + 1 <<  " " << rr <<endl;
        else
            puts("-1");
    }
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值