Technocup 2020-Elimination Round 1(CF1413)部分题解&&总结

先总结一下。

在这里插入图片描述
A竟然想了 5 5 5分钟,同机房的人都切掉了之后才开始做。

B因为RE错了 2 2 2次,罚了许多分;主要是看到 W A WA WA,以为思路错了,事实上是数组开笑了

C想了半天,无果。开 D D D,切掉。

然后回到 C C C,一个同机房的巨佬做出来之后,全机房的人问他怎么做;结果啥也没听懂,比赛结束后才恍然大悟。

用了自己的一个 636 636 636分的,才打一场的灰名小号打,应该能上分吧……

Solution

A

对于每一对 ( i , j ) (i,j) (i,j),配上 ( j , − i ) (j,-i) (j,i)即可。

B

开桶记录,乱搞即可。

C

首先,我加强一下数据: 可能有 m m m个琴弦, m ≤ 100000 m≤100000 m100000

我们考虑贪心。首先,为了将可选的方案数量大幅减少,我们将这两个数组分别减去它们各自的最小值。可以发现,对于 b b b中的一个数 k k k,要么选择 a a a k k k的前驱,要么选择后驱。这可以用决策包容性来证明。

于是,我们在对 a a a排序后,对于 b b b中的每一个数通过二分找到 a a a中它的前驱与后驱。记 c i c_i ci表示 b i − a j b_i-a_j biaj d i d_i di表示 b i − a k b_i-a_k biak,其中 a j a_j aj a a a b i b_i bi的前驱, a k a_k ak a a a b j b_j bj的后驱。

我们将 c c c从小到大排序,同时使 c c c中的值与 d d d中的值相对应。可以发现,对于每一个位置的配对,决策在 c c c d d d中;并且在最优解中,一定是前面一段先选择了 c c c,后选择了 d d d

我们枚举这个位置,使得在这个位置及其之前选择了 c c c,后面选择了 d d d,即这个位置为差的最大值。至于差的最小值,为后面选择的 d d d中的最小值,可以通过预处理后缀最小值来 O ( 1 ) O(1) O(1)查询。我们求出每一对的差的最大值减去最小值,然后取 m i n min min即可。

总时间复杂度 O ( n ( l o g n + l o g m ) + m l o g m ) O(n(logn+logm)+mlogm) O(n(logn+logm)+mlogm)

花絮: 一位机房巨佬Guess00赛时把这题切了,我们一起膜拜他吧! orz

D

一道水的构造题。

我们从后往前扫一遍,维护一个堆,记录下当前扫到的物品的从小到大排序的结果;每次取出堆顶作为当前这一次放进去的物品价值,并继续向前扫。

最后,我们再用相同的方式,使用一个堆,从前往后扫一遍,用来判断我们这种构造方案是否可行。如果可行直接输出方案,否则输出 − 1 -1 1

时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)。注意数组开大

Code

A

#include <bits/stdc++.h>
#define int long long
using namespace std;

int t,n;
int a[200005];

signed main()
{
    
    
	cin>>t;
	while (t--)
	{
    
    
		cin>>n;
		for (int i=1;i<=n;i++)  cin>>a[i];
		for (int i=1;i<=n;i++)
		{
    
    
			if (i%2==1)  cout<<a[i+1]<<' ';
			else cout<<-a[i-1]<<' ';
		}
		cout<<endl;
	}
	return 0;
}

B

#include <bits/stdc++.h>
#define int long long
using namespace std;

int t,n,m,x;
int a[1005][1005],v[1000005],num[1000005],ans[1005][1005];

signed main()
{
    
    
	cin>>t;
	while (t--)
	{
    
    
		cin>>n>>m;
		for (int i=1;i<=n*m;i++)  v[i]=num[i]=0;
		for (int i=1;i<=n;i++)
		{
    
    
			for (int j=1;j<=m;j++)  ans[i][j]=0;
		}
		for (int i=1;i<=n;i++)
		{
    
    
			cin>>a[i][1];
			v[a[i][1]]=i;
			for (int j=2;j<=m;j++)  cin>>a[i][j];
		}
		for (int i=1;i<=m;i++)
		{
    
    
			for (int j=1;j<=n;j++)
			{
    
    
				cin>>x;
				num[v[x]]=j;
			}
		}
		for (int i=1;i<=n;i++)
		{
    
    
			for (int j=1;j<=m;j++)  ans[num[i]][j]=a[i][j];
		}
		for (int i=1;i<=n;i++)
		{
    
    
			for (int j=1;j<=m;j++)  cout<<ans[i][j]<<' ';
			cout<<endl;
		}
	}
	return 0;
}

C

//by gh
#include<bits/stdc++.h>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#define DEBUG cerr << "Passing Line " << __LINE__<< " in Function [" << __FUNCTION__ << "].\n";
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;

const int INF = 0x3f3f3f3f;
const ll llINF = 1e18;
const int MAXN = 1e5 + 5;
const int MAXM = 10;
const int m = 6;

int n;
int a[MAXN],b[MAXN],suf[MAXN];
pii c[MAXN];

int main(){
    
    
    // freopen("data.in","r",stdin);
    // freopen("data.out","w",stdout);
    for(int i = 1;i <= m;i++)
        scanf("%d",&a[i]);
    scanf("%d",&n);
    for(int i = 1;i <= n;i++)
        scanf("%d",&b[i]);
    sort(a + 1,a + 1 + m);
    sort(b + 1,b + 1 + n);
    for(int i = 2;i <= m;i++)
        a[i] -= a[1];
    a[1] = 0;
    for(int i = 2;i <= n;i++)
        b[i] -= b[1];
    b[1] = 0;
    for(int i = 1;i <= n;i++){
    
    
        int x = upper_bound(a + 1,a + 1 + m,b[i]) - a - 1;
        c[i].first = b[i] - a[x];
        x = lower_bound(a + 1,a + 1 + m,b[i]) - a;
        if(x == m + 1)
            c[i].second = -INF;
        else
            c[i].second = b[i] - a[x];
    }
    sort(c + 1,c + 1 + n);
    int ans = INF;
    suf[n] = c[n].second;
    for(int i = n - 1;i >= 1;i--)
        suf[i] = min(suf[i + 1],c[i].second);
    for(int i = 1;i <= n;i++)
        ans = min(ans,c[i].first - suf[i + 1]);
    printf("%d\n",ans);
    return 0;
}

D

#include <bits/stdc++.h>
#define int long long
using namespace std;

int n,pos=0,a[200005];

struct node
{
    
    
	char x;
	int num;
}tmp[200005];

signed main()
{
    
    
	cin>>n;
	for (int i=1;i<=2*n;i++)
	{
    
    
		cin>>tmp[i].x;
		if (tmp[i].x=='-')  cin>>tmp[i].num;
	}
	priority_queue<int,vector<int>,greater<int> > q;
	for (int i=2*n;i>=1;i--)
	{
    
    
		if (tmp[i].x=='-')
		{
    
    
			int now=tmp[i].num;
			q.push(now);
		}
		else
		{
    
    
			int x=q.top();
			a[i]=x;
			q.pop();
		}
	}
	for (int i=1;i<=2*n;i++)
	{
    
    
		if (tmp[i].x=='+')
		{
    
    
			int now=tmp[i].num;
			q.push(now);
		}
		else
		{
    
    
			int x=q.top();
			if (tmp[i].num!=x)  return cout<<"NO"<<endl,0;
			q.pop();
		}
	}
	cout<<"YES"<<endl;
	for (int i=1;i<=2*n;i++)
	{
    
    
		if (a[i])  cout<<a[i]<<' ';
	}
	cout<<endl;
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Cherrt/article/details/109280326
今日推荐