补题--7 (Round 76 (Rated for Div. 2))


codeforce的网址: https://codeforces.com/contest/1257
比赛网址: https://vjudge.net/contest/381169

A(Rated for Div. 2 E)

题意:
3堆数,要求使得第一堆的数为前缀,第三堆数为后缀,第二堆数为剩下的数,要求最少调整多少个数的位置使得要求成立。
官方代码:

#include <iomanip>
#define LL long long
using namespace std;
const int N=2e5+5;
int s[N],st[N];
int main()
{
	int n,a,b,c;
	scanf("%d %d %d",&a,&b,&c);
	n=a+b+c;
	for(int i=1;i<=a;i++)
	{
		int x; 
		scanf("%d",&x);
		st[x]=1;
	}
	for(int i=1;i<=b;i++) 
	{
		int x;
		scanf("%d",&x);
		st[x]=2;
	}
	for(int i=1;i<=c;i++)
	{
		int x;
		scanf("%d",&x);
		st[x]=3;
	}
	int len=0;
	for(int i=1;i<=n;i++)
		if(len==0||s[len-1]<=st[i]) s[len++]=st[i];
		else
		{
			int k=upper_bound(s,s+len,st[i])-s;
			s[k]=st[i];
		}
	printf("%d\n",n-len);
	return 0;
}

B(Rated for Div. 2 C)

题意:
就是长度为n的数组中找到最多的那个数的,然后输出俩个相同的数之间最小的数字个数。
数组长度小于2或者没有则输出-1;
思路:
首先应该找到最多的那个数,然后在找到俩个相距最小的这个数。
官方代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdio>
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
ll a[200005],vis[200005],n,t,m,x,i,j,k,sum,ans,cnt,Max,Min;
int main()
{
    cin>>t;
	while (t--)
	{
		cin >> n;
		memset(vis,0,sizeof(vis));//记忆数组!!!之前学过,这里可以用到
		for (i = 1; i <= n; i++)
			scanf("%d", &a[i]);
		Min = INF;//定义其无限大
		for (i = 1; i <= n; i++)
		{
			if (vis[a[i]] == 0)
				vis[a[i]] = i;//首先给定一个数组复制原数组
			else
			{
				Min = min(Min, i - vis[a[i]] + 1);//然后寻找俩个相同字符串之间最小的距离
				vis[a[i]] = i;
			}
		}
		if (Min == INF)//没有相同的,min的值不变
			cout << -1 << endl;
		else
			cout << Min << endl;
	}
	return 0;
}

C(Rated for Div. 2 A)

题意:
就是俩个a,b学生的位置,
和一共有n个学生,
已经可以交换x次,
然后求出这俩个学生距离最远距离。
思路:
求这俩个数之间的距离首先先求出这两个数之间的距离,
然后看之间距离加上可以移动的距离是否小于n-1,小于之间输出距离加x,大于则输出n-1;

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#define max(a,b) a>b?a:b;
int main()
{
	int t, x, n, a, b;
	scanf("%d", &t);
	while (t--)
	{
		int res = 0;
		scanf("%d %d %d %d", &n, &x, &a, &b);
		res = max(a - b, b - a);
		if (res + x <= (n - 1))
		{
			res = res + x;
		}
		else
		{
			res = n - 1;
		}
		printf("%d\n", res);
	}
	return 0;
}

D(Rated for Div. 2 D)

题意:
就是有英雄m个,他分别由力量p,耐力s,还有n个怪兽,力量ai,英雄的力量大于怪兽则可以打死,但是耐力要减去打死的怪兽的数量。没耐力了则英雄今天就不打了。看打到最后一个怪事要多少天,然后如果不可以就输出-1.
思路:
先找到最大的力气然后根据游戏规则进行。
官方大佬代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const int N=2e5+10;
int a[N],mx[N];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,m;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]),mx[i]=0;
        scanf("%d",&m);
        int x,y;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            mx[y]=max(mx[y],x);//每个耐力值的最大力量
        }
        for(int i=n-1;i>=1;i--)
        {
            mx[i]=max(mx[i],mx[i+1]);
        }
        int pos=0,ans=0,flag=0;
        while(pos<n)
        {
            ans++;
            int l=0,maxp=a[pos+1];
            while(maxp<=mx[l+1]&&pos+1+l<=n)
            {
                l++;
                maxp=max(maxp,a[l+pos+1]);
            }
            if(l==0)
            {
                flag=1;
                break;
            }
            pos+=l;
        }
        if(!flag) printf("%d\n",ans);
        else printf("-1\n");
    }
    return 0;
}

E(Rated for Div. 2 F)

题意:
如果它们的二进制所含1的个数相同,则输出1的个数,否则-1.
大佬代码和讲解

#include<bits/stdc++.h>
 
using namespace std;
 
int popCount(int x, int start) {
	int bits = 0;
	for (int i = start; i < start + 15; i++)
		bits += bool(x & 1 << i);
	return bits;
}
 
int main()
{
	int n;	scanf("%d", &n);
 
	vector <int> v(n);
	for (int& x : v) scanf("%d", &x);
 
	map < vector <int>, int > exist;
	for (int x = 0; x < (1 << 15); x++) {
		vector <int> cur(n);
		for (int i = 0; i < n; i++)
			cur[i] = popCount(v[i] ^ x, 0);
		
		vector <int> diff;
		for (int i = 1; i < n; i++)
			diff.push_back(-(cur[i] - cur[i - 1]));
 
		exist[diff] = x;
	}
 
	for (int x = 0; x < (1 << 15); x++) {
		vector <int> cur(n);
		for (int i = 0; i < n; i++)
			cur[i] = popCount(v[i] ^ (x << 15), 15);
		
		vector <int> diff;
		for (int i = 1; i < n; i++)
			diff.push_back(cur[i] - cur[i - 1]);
 
		if (exist.count(diff))
			return 0* printf("%d\n", (exist[diff] | (x << 15)));
	}
 
	puts("-1");
 
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值