牛客练习赛34

版权声明:转就转吧~~记得声明噢~~ https://blog.csdn.net/Soul_97/article/details/85010453

https://ac.nowcoder.com/acm/contest/297#question

A题

偶数不变,奇数-1,用字符串处理

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 100;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
 
int main()
{
    string s;
    int T;
    cin >> T;
    while(T --){
        cin >> s;
        if((s[s.size()-1]-'0')%2){
            s[s.size()-1] = (s[s.size()-1]-'0')-1 + '0';
        }
        cout << s << '\n';
    }
    return 0;
}

B题

map存一下数字的个数,求负数和s1,正数和s2,看判断s1+s2的结果

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 100;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
map<int,int> m;
int n,t;
int main()
{
    ll s1,s2;
    s1 = s2 = 0;
    cin >> n;
    for(int i = 1;i <= n;i ++){
        cin >> t;
        m[t] ++;
        if(t >= 0)
            s1 += t;
        else
            s2 += t;
    }
    if(abs(s1+s2)%2)
        cout << -1 << endl;
    else{
        printf("%d\n",m[(s1+s2)/2]==0?-1:m[(s1+s2)/2]);
    }
    return 0;
}

C题

用差分数组d记录下覆盖情况,然后求遍前缀和,当差分数组d中某个位置d[i]为0时,则表示此时这个点没有被覆盖,d[i]为1时记录下来,对应前缀和数组s[i] += 1,此时表示仅有一条边覆盖,大于1就是多边覆盖了,最终对前缀和数组求区间差找最小即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 100;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
int l[N],r[N],d[N],s[N];
int main()
{
    int n,m;
    cin >> n >> m;
    for(int i = 1;i <= m;i ++)
        cin >> l[i] >> r[i],d[l[i]] ++,d[r[i]+1] --;
    int cnt = 0;
    for(int i = 1;i <= n;i ++){
        s[i] += s[i-1];
        d[i] += d[i-1];
        if(!d[i]) cnt ++;
        if(d[i]==1) s[i] ++;
    }
    int ans = INF,pos;
    for(int i = 1;i <= m;i ++){
        int tmp = s[r[i]] - s[l[i]-1];
        if(tmp <= ans){
            ans = tmp;
            pos = i;
        }
    }
    cout << pos << " " << ans+cnt <<endl;
    return 0;
}

D题

先把所有面值从小到大排个序,设s为当前面值总和,设x = s + 1  x的意义是需要凑的面值 

第一个数必须为1,第二个数可以为1,也可以为2,但是不能为3  如果为3的话面值为2的情况就凑不出来了

所以是 当前面值a[i] <=  x  才可以  如果满足的话 则 s+a[i]更新下一次需要凑的面值   最后再判断是不是大于等于m

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 100;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
int n,m;
int a[1005];
int main()
{
    ll s = 0;
    cin >> n >> m;
    for(int i = 1;i <= n;i ++)
        cin >> a[i];
    sort(a + 1,a + n + 1);
    for(int i = 1;i <= n;i ++){
        if(a[i] <= s + 1){
            s += a[i];
        }else{
            break;
        }
    }
    if(s >= m)
        cout << "YES" << '\n';
    else
        cout << "NO" << '\n';
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Soul_97/article/details/85010453