Codeforces Round #661 (Div. 3)——A.B.C.D.

Codeforces Round #661 (Div. 3)

A. Remove Smallest

题意:您可以选择两个索引i和j(i≠j),以使ai和aj之间的绝对差不超过一个(| ai-aj |≤1),并删除这两个元素中的最小值。如果两个元素相等,则可以删除其中任何一个(但只能删除一个)。
您的任务是查找是否可以使用多次(可能为零)此类移动来获取仅包含一个元素的数组。
思路:排序后的相邻两个如果差值大于1就不行。
代码

#include <iostream>
#include <math.h>
#include <algorithm>
#include <cmath>
#include <string.h>
#include <stdio.h>
#include<queue>
using namespace std;
#define INF 1000000
typedef pair<int,int>P;
int n,a[100];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=0; i<n; i++)
            scanf("%d",&a[i]);
        sort(a,a+n);
        int flag=0;
        for(int i=1; i<n; i++)
        {
            if(a[i]-a[i-1]>1)
            {
                flag=1;
                break;
            }
        }
        if(flag==1)
            printf("NO\n");
        else
            printf("YES\n");
    }
    return 0;
}

B. Gifts Fixing

题意:在移动过程中,您可以选择1≤i≤n的礼物并执行以下操作之一:
从此礼物中只吃一个糖果(将AI减一);
从此礼物中只吃一个橙子(将bi减一);
从此礼物中只吃一个糖果和一个橙子(将ai和bi都减一)。
当然,如果礼物中没有糖果或橙子,就不能吃(所以ai和bi都不能小于零)。
如上所述,所有礼物应相等。这意味着在经过一系列移动之后,应满足以下两个条件:a1 = a2 =⋯= an和b1 = b2 =⋯= bn(并且ai等于bi并不是必需的)。
您的任务是找到均衡所有给定礼物所需的最小移动次数。
思路:找到最小的a数组里的,找到最小的b数组里的,再一遍for循环,找出a数组与mina差值,b数组与minb的差值,加上大的那个差值,因为可以(将ai和bi都减一)。最后的和就是答案。
代码

#include <iostream>
#include <math.h>
#include <algorithm>
#include <cmath>
#include <string.h>
#include <stdio.h>
#include<queue>
using namespace std;
#define INF 1000000
typedef pair<int,int>P;
int n;
long long a[100],b[100];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        long long mina=1000000000,minb=1000000000;
        for(int i=0; i<n; i++)
        {
            scanf("%lld",&a[i]);
            mina=min(a[i],mina);
        }
        for(int i=0; i<n; i++)
        {
            scanf("%lld",&b[i]);
            minb=min(minb,b[i]);
        }
        long long ans=0;
        //printf("%lld %lld\n",mina,minb);
        for(int i=0; i<n; i++)
        {
            long long  ta=a[i]-mina;
            long long tb=b[i]-minb;
            long long tmp=max(ta,tb);
            ans+=tmp;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

C. Boats Competition

题意:有n个人想参加划船比赛。第i个参与者的权重是wi。只有两人组成的团队可以参加比赛。如果有k个团队(a1,b1),(a2,b2),…,(ak,bk),其中ai是第i个团队的第一个参与者的权重,bi是第二个团队的权重第i个团队的参与者,则必须满足条件a1 + b1 = a2 + b2 =⋯= ak + bk = s,其中s是每个团队的总权重。问有多少个团队可以参赛。
思路:就是范围都是50,任意两个人的加和最大也就是100,所以用2到100(最小值是1),遍历s,然后再用尺取法,找到有多少对是==i的。最后99遍扫完之后输出最大值。(做题的时候忘记先给数组排序再进行尺取法)。
代码

#include <iostream>
#include <math.h>
#include <algorithm>
#include <cmath>
#include <string.h>
#include <stdio.h>
#include<queue>
using namespace std;
#define INF 1000000
typedef pair<int,int>P;
int n;
int a[100],b[100];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=0; i<n; i++)
            scanf("%d",&a[i]);
        sort(a,a+n);
        int ans=0;
        for(int i=2; i<=100; i++)
        {
            int l=0;
            int r=n-1;
            int num=0;
            while(l<r)
            {
                if((a[l]+a[r])==i)
                {
                    num++;
                    l++,r--;
                }
                else if(a[l]+a[r]>i)
                    r--;
                else if(a[l]+a[r]<i)
                    l++;
            }
            ans=max(ans,num);
        }
        printf("%d\n",ans);
    }
    return 0;
}

D. Binary String To Subsequences(补)

题意:给定一个字符串由0、1组成,问最少有几个字符串是01间隔的(010101……或者101010……)。输出最少的个数和每个字符在第几个子字符串。
思路:我研究的代码是用两个栈来存,第一个分两个部分,分别存0字符的位置信息,1字符位置信息,另外一个栈存字符串每个位置的位置信息。
举例说明:100011

  1. 首先第一个字符是1 之前未出现过子字符串,这是第一个,cnt++ (1)1字符栈内先存入cnt,表示这个1字符的位置1号字符串
    存入改位置的位置信息。

  2. 然后是进来0,先看看1号字符串内是否有值,发现有,那这个0的位置信息与1字符串的最前面的相同(先进去的),
    0字符栈存入找到的1字符栈的数值(第几个子字符串) 存入改位置的位置信息。
    此时要把1字符栈的这个1的位置信息删去,因为已经有出现下一个0,他不可能再接别的0

  3. 然后还是0,看看1字符栈内没有1了,所以此时的0就要新开一个子字符串,cnt++;(2)
    0字符栈内先存入cnt,表示这个0字符的位置2号字符串
    存入改位置的位置信息。

  4. 在之后是0,同上一步操作一样。

  5. 是1,先判断0字符栈内是否有值,发现有,则存入0字符栈内最前面的子字符串号,再记录再大的位置信息栈中,然后将改信息从0字符站内删除。

  6. 再来还是1,先判断0字符栈内是否有值,发现有,则存入0字符栈内最前面的子字符串号,再记录再大的位置信息栈中,然后将改信息从0字符站内删除。

就好像是子字符串的号数在0和1的字符栈内只能存在一个

100011

1
‘1’ ①
0
‘1’ ①
‘0’ ①
0
‘0’ ①
‘0’ ②
0
‘0’ ①
‘0’ ②
‘0’ ③
1
‘0’ ①
‘0’ ②
‘0’ ③
‘1’ ①
1
‘0’ ②
‘0’ ③
‘1’ ①
’1‘ ②
代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        int n;
        cin >> n;
        string s;
        cin >> s;
        int cnt = 0;
        vector<int> seq[2];
        vector<int> ans;
        ans.reserve(n);
        for(int i=0; i<n; i++)
        {
            int x=s[i]-'0';
            if(seq[!x].empty())
            {
                seq[x].push_back(++cnt);
                ans.push_back(cnt);
            }
            else
            {
                seq[x].push_back(seq[!x].back());
                ans.push_back(seq[!x].back());
                seq[!x].pop_back();
            }
        }
        cout << cnt << "\n";
        for (int i = 0; i < n; ++i)
            cout << ans[i] << " \n"[i == n - 1];
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值