首页 > 其他分享 >Codeforces Round 892 (Div. 2)

Codeforces Round 892 (Div. 2)

时间:2023-08-15 17:11:41浏览次数:55  
标签:892 ch 数列 int Codeforces leq 最小值 排列 Div

Codeforces Round 892 (Div. 2)

A. United We Stand

简述题意

给定一个长度为 $ n $ 的数列 $ a $ ,要求将 $ a $ 的每个元素分配到数列 $ b $ ,$ c $ 中,满足以下两个要求

  1. $ b,c $ 不为空,即 $ l_b \geq 1 , l_c \geq 1 $ 。
  2. 对于任意 $ i $ 和 $ j $ $ (1\leq i \leq l_b ,1\leq j \leq l_c) $ ,$ c_j $ 不为 $ b_i $ 的约数 。

如果有分配方案满足两个条件,第一行输出$ l_b,l_c $ 接下来两行分别输出数列$ b,c $ 。
如果没有分配方案满足两个条件则输出-1

共有 $ T $ 组数据,$ T\leq500 $ ,$ 2 \leq n \leq 100 $ ,$ 1 \leq a_i \leq 10^9 $

思路

首先,对于 $ \forall x,y(x>y) $ , $ x $ 一定不为 $ y $ 的约数,基于这个事实,可以考虑将 $ a $ 中的所有最大值放进 $ b $ 中,其余的放进 $ a $ 中,这样便能满足条件2;但是有一种特殊情况便是 $ a $ 中只由一个数字组成,如果仍然依照上面的思路将所有最大值放进数组 $ b $ 中,就会导致 $ a $ 为空,如果在 $ a,b $ 皆不为空的情况下无论如何分配 $ a $ 中的元素均不能满足条件1,所以遇见这种特殊情况的时候直接输出-1

代码实现

没什么需要注意的,排序之后特判一下特殊情况,从后面往前面找到第一次出现最大值的位置 $ x $ , $ l_b $ 就为 $ x-1 $ ,$ l_c $ 则为 $ n-x+1 $ ,然后直接输出 $ b,c $ 即可。

代码如下:


#include<bits/stdc++.h>
using namespace std;
const unsigned int N=105;
int n,a[N];
inline int r(){
    int x=0,y=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-')
        y=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*y;
}
bool cmp(int x,int y){
    return x<y;
}
void solve(){
    n=r();
    for(register int i=1;i<=n;i++)
    a[i]=r();
    sort(a+1,a+n+1,cmp);
    if(a[n]==a[1]){
        puts("-1");
        return;
    }
    int x=n;
    for(register int i=n;i>1;i--){
        if(a[i-1]==a[i]){
            x=i-1;
            continue;
        }
        break;
    }
    printf("%d ",x-1);
    printf("%d\n",n-x+1);
    for(register int i=1;i<=x-1;i++)
    printf("%d ",a[i]);
    printf("\n");
    for(register int i=x;i<=n;i++)
    printf("%d ",a[i]);
    printf("\n");
}
signed main(){
    int T=r();
    while(T--)
    solve();
}

B. Olya and Game with Arrays

简述题意

这里有 $ n $ 个数列,第 $ i $ 个数列包含 $ m_i $ 个正整数 。

现在你可以在每个数列中挑出至多一个元素移动至另外一个数列(当然也可以不移动),一个数列中可以接受多个元素加入进来,但是一个数列中只有一个元素可以被挑出移动至其他数列,所有操作在同一时刻完成 。

美丽值的定义是每个数列中的最小值之和,即 $ \sum_{i=1}^{n} min_{j=1}^{m_i}a_{i,j} $ 。

现在求通过操作后,这 $ n $ 个数列最大的美丽值 。

共有 $ T $ 组数据 , $ 1 \leq T \leq 25000 $ ,$ 1 \leq n \leq 25000 $ ,$ 2 \leq m \leq 50000 $ ,$ 1 \leq a_{i,j} \leq 10^9 $ 。

思路

我们先思考一下一个数列如何移动能让这次移动对答案的贡献最大,肯定是将数列中的最小值移出去,若第 $ i $ 个数列中的最小值为 $ x_i $,次小值为 $ y_i $ 那么将这个数列中的最小值移出去对答案的贡献是 $ y_i-x_i $ ,为了让答案尽可能的大,我们先假设每个数列都将它的次小值移出去,当前的答案是 $ \sum_{i=1}^{n}y_i $ ,但是必须要找到一个数列来接受这些被移出的最小值,我们发现,若第 $ i $ 个数列接受了这些最小值,答案将会减去 $ y_i - min_{i=1}^{n} x_i $ ,为了让答案最大,所以我们需要让 $ y_i $ 最小,所以最终的答案就是 $ \sum_{i=1}^{n}y_i -min_{j=1}^{n} y_j+min_{k=1}^{n}x_k $ 。

代码实现

由于影响答案的只有每个数列的最小值和次小值,所以在读入的时候记录每一个数列的最小值和次小值,在记录每个数列最小值的最小值每个数列次小值的最小值 即可 ,注意多测清空,开long long

代码如下

#include<bits/stdc++.h>
#define int long long
#define INF (int)1e9+15
using namespace std;
const unsigned int N=25005;
int n,m,mxa[N],mxb[N];//mxa记录每个数列的最小值,mxb记录每个数列的次小值
inline int r(){
    int x=0,y=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-')
        y=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*y;
}
void solve(){
    int ans=0,mm=INF;//mm记录所有数列中的最小值
    n=r();
    for(register int i=1;i<=n;i++){
        m=r();
        mxa[i]=mxb[i]=INF;
        for(register int j=1;j<=m;j++){
            int x=r();
            mm=min(mm,x);
            if(x<mxa[i]){
                mxb[i]=mxa[i];
                mxa[i]=x;
                continue;
            }
            mxb[i]=min(x,mxb[i]);
        }
    }
    for(register int i=1;i<=n;i++){
        int tmp=mm;
        for(register int j=1;j<=n;j++){
            if(i==j)
            continue;
            //printf("tmp=%d\n",tmp);
            tmp+=mxb[j];
        }
        ans=max(ans,tmp);
    }
    printf("%lld\n",ans);
    return;
}
signed main(){
    int T=r();
    while(T--)
    solve();
}

C.Another Permutation Problem

题意简述

给出一个 $ n $ ,你可以任意改变长度为 $ n $ 的排列中的元素位置使得这个排列的价值最大 。

长度为 $ n $ 排列的定义是 $ \forall i \in [1,n] $ , $ p_i \in [1,n] $ 且排列中没有重复出现的元素 。

排列 $ p $ 的价值的定义为 : 排列中的每一个元素的大小乘上它在排列中的位置减去排列中一个数乘上他所在的位置的最大值,即 $ (\sum_{i=1}^{n} p_i \cdot i)-(max_{j=1}^{n}p_j \cdot j) $ 。

求改变排列中元素的顺序后排列的最大值 。

共有 $ T $ 组数据 ,$ 1 \leq T \leq 30 $ , $ 2 \leq n \leq 250 $ , 保证每组数据 $ n $ 的总和不超过 $ 500 $ 。

思路

第一眼看见这道题没有任何思路,看样例感觉像是反转一下 $ p_n $ 和 $ p_{n-1} $ 的位置,但是通过暴力求全排列算出的答案发现 $ n=5 $ 时并不符合这个规律,在通过暴力求全排列求 $ n $ 更大时候的方案符合 $ p $ 为 $
1,2,3,...,x,n,n-1,n-2,...,x+2,x+1 $

观察 $ n $ 的大小,我们可以枚举 $ x $ 的位置,每次枚举后算出当前方案下排列的价值,取最大值输出即可,时间复杂度 $ O(n^2) $ 。

代码

注意多测清空

#include<bits/stdc++.h>
#define INF 0x7fffffff
using namespace std;
const unsigned int N=255;
int n,sol[N],tmp[N],ans,t_max=-INF;
bool vis[N];
inline int r(){
	int x=0,y=1;
	char ch=getchar();
	while(!isdigit(ch)){
		if(ch=='-')
		y=-1;
		ch=getchar();
	}
	while(isdigit(ch)){
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return x*y;
}
int get_sol(int x){//算出当前方案下排列的价值
	int res=0;
	t_max=-INF;
	for(register int i=1;i<=x;i++){
		res+=i*i;
		t_max=max(t_max,i*i);
	}
	for(register int i=x+1;i<=n;i++){
		res+=(n-(i-(x+1)))*i;
		t_max=max(t_max,(n-(i-(x+1)))*i);
	}
	res-=t_max;
	return res;
}
void solve(){
	n=r();
	ans=0;
	for(register int i=0;i<=n;i++)
	ans=max(get_sol(i),ans);
	printf("%d\n",ans);
	return;
}
signed main(){
	int T=r();
	while(T--)
	solve();
}

标签:892,ch,数列,int,Codeforces,leq,最小值,排列,Div
From: https://www.cnblogs.com/suyunqiaoKID/p/17631844.html

相关文章

  • Codeforces Global Round 15
    CodeforcesGlobalRound15A-SubsequencePermutation思路:找出原串与排序后的串不同的个数#include<bits/stdc++.h>usingnamespacestd;voidsolve(){intn;cin>>n;strings;cin>>s;stringt=s;sort(t.begin(),t.end());intans=0;......
  • Codeforces Round 892 (Div. 2) A-E
    A.UnitedWeStand题意:给出一个长为\(n\)的数组\(a\),将其中的元素分别放到空数组\(b\)和\(c\)中,使得\(c\)中的任意一个元素都不是\(b\)中任意一个元素的因数,并且两个数组都不是空数组Solution把\(a\)中最小的数放到\(b\),其它的都放到\(c\),一定可以保证要求成立voidsolve(){......
  • Codeforces Ronud 892(Div.2)
    CodeforcesRonud892(Div.2)关于A题我有话说传送门题意给定一个长度为n的数组a,问能否将元素全部放入两个空数组b和c中,使得b和c数组同时满足非空,且c数组中没有任何数是b数组中的数的除数,如果可以输出一种存储方案,不可以就输出-1思路当天晚上一开始没有做出来,我一开始的思路是......
  • CodeForces-1798#B 题解
    正文开个数组\(last_k\)统计\(a_{i,j}\)最后买彩票的时间,再开一排桶\(day_t\)记录该天最后买彩票的有哪些人(即:有\(p\)满足\(last_p=t\)的集合)。将\(last_k\)放入\(day_t\)中,判断\(day_t\)中是否存在空桶,若有则无解(因为没有人在当天是最后买彩票的)。因为本题是......
  • 2023.08.12 codeforces round 892 div2
    年轻人的第三场div2(已完成:ABCDE)rank:1265solved:4ratingchange:+276newrating:1323A.UnitedWeStand题意:给定一个数列a,问是否能分成两个非空的数列b和c,使得c中任意一个数不是b中任意一个数的因子;若x是y的因子则有x<=y;因此不妨将数列的最大值放入c,把剩下的数放入b;注意数列中......
  • div 加阴影
    要为<div>元素添加阴影效果,你可以使用CSS的box-shadow属性。以下是一个示例:<style>.shadow-box{width:200px;height:200px;box-shadow:02px4pxrgba(0,0,0,0.2);}</style><divclass="shadow-box"><!--这里是div内容--......
  • Codeforces Round 892 (Div. 2)
    Preface最接近橙名的一场,可惜给我一个小时也没想到E的关键点,后面徐神一点拨就懂了虽然现在这个号已经到渡劫局了但因为之前有场比赛给了ztc一份代码然后他直接没咋改交上去了,估计下次rollRating的时候这个号要掉200来分了嘛不过也无所谓反正下次打另一个号冲分,而且像我这种永......
  • 2023年多校联训NOIP层测试7+【LGR-149-Div.3】洛谷基础赛 #2 & qw Round -1
    2023年多校联训NOIP层测试7,集训欢乐赛,绝对欢乐,童叟无欺赛时在回家的路上+睡觉,所以没打。\(T1\)近似ybtOJ2049:【例5.19】字符串判等本题少了对空格的判断,水题。PS:题面和题解中都写了文件输入输出,测评时没有文件输入输出是几个意思,艹。#include<bits/stdc++.h>usingname......
  • 【题解】Educational Codeforces Round 146(CF1814)
    而且怎么感觉E,F比D要简单很多,大概是因为比较套路吧[惊恐]A.Coins题目描述:本题一共有\(t\)组数据。每组数据包含两个整数\(n\)和\(k\),如果存在两个非负整数\(x,y\),满足\(2\timesx+k\timesy=n\),输出YES,否则输出NO(yes,Yes,NO,nO均可)。题目分析:注意到\(y\)可......
  • Codeforces Round 892 (Div. 2)(vp)
    CodeforcesRound892(Div.2)AUnitedWeStand题意:给一个数组,让你把它分成两个数组,第二个数组里的数不能是第一个数组里的数的除数,先输出两个数组的长度,依次输出两个数组的数,如果无法分出来,输出-1思路:如果数的种类只有一种一定不行,反之一定行,对于可行的情况,我们把最大的......