CF1189(Div.2)题解(全)
传送门
显然不是当场AK,而且D2&E&F都看了题解
PS:如果觉得有帮助,给个赞呗
A. Keanu Reeves
题意:定义0的个数与1的个数不同的01串为"好串".
给你一个长为 n ( 1 ≤ n ≤ 100 ) n(1≤n≤100) n(1≤n≤100)的串 s s s,把它分成尽量少的"好串".输出最少分成的段数和这些段.
题解:考虑原串 s s s:
- s s s是好串:不用分,直接输出
- s s s非好串:意味着0的个数与1的个数相同.所以串s2…n一定是好串(因为s1要么是0要么是1).又因为s1显然是好串,所以一定可以分为s1和s2…n这两个好串
时间空间显然 O ( n ) O(n) O(n)(但我在比赛时却瞎搞了个 O ( n 2 ) O(n^2) O(n2),太low就只贴 O ( n ) O(n) O(n)代码了)
//Wan Hong 2.2
//notebook
#include<iostream>
#include<cstdio>
#include<cstring>
typedef long long ll;
char a[5011];
int main()
{
ll n,c0=0,c1=0;
std::cin>>n>>(a+1);
for(ll i=strlen(a+1);i;--i)
if(a[i]=='1')++c1;
else ++c0;
if(c1!=c0)std::cout<<1<<std::endl<<(a+1);
else std::cout<<2<<std::endl<<a[1]<<" "<<(a+2);
return 0;
}
B. Number Circle
题意:给出一个长为 n ( 3 ≤ n ≤ 1 0 5 ) n(3≤n≤10^5) n(3≤n≤105)的序列 a 1 , a 2 , a 3 . . . a n ( 1 ≤ a i ≤ 1 0 9 ) a_1,a_2,a_3...a_n(1≤a_i≤10^9) a1,a2,a3...an(1≤ai≤109).求能否把这n个数摆成一个圆,使每一个数都严格小于它左右两个数的和.若能,输出"YES",并打印任意一种方案;若不能,输出"NO".
题解:考虑构造.
先把序列排序,使 a i ≤ a j ( 1 ≤ i < j ≤ n ) a_i≤a_{j}(1≤i<j≤n) ai≤aj(1≤i<j≤n)那么,只要将 a i a_i ai与 a j a_{j} aj摆在一起, a i a_i ai就一定符合要求.
但问题来了, a n a_n an怎么办呢?考虑将 a n a_n an与 a n − 1 , a n − 2 a_{n-1},a_{n-2} an−1,an−2摆在一起,如果这样也不行,那么 a n a_n an一定没办法符合要求了(因为 a n , a n − 1 , a n − 2 a_n,a_{n-1},a_{n-2} an,an−1,an−2是最大的两个)
所以最后的最优序列(之一)就是 a 1 , a 2 . . . a n − 4 , a n − 3 , a n − 2 , a n , a n − 1 a_1,a_2...a_{n-4},a_{n-3},a_{n-2},a_n,a_{n-1} a1,a2...an−4,an−3,an−2,an,an−1
(由于是个圆,所以 a 1 a_1 a1与 a n − 1 a_{n-1} an−1相邻,也是一定合法的)
复杂度瓶颈在于排序, O ( n l o g n ) O(nlogn) O(nlogn).
//Wan Hong 2.2
//notebook
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long ll;//到/**********/之前都是我的板子,之后的代码不再提及
#define INF (1ll<<58)
ll read()//快读,之后不再提及
{
ll x=0,f=1;
char c;
do
{
c=getchar();
if(c=='-')f=-1;
}while(c<'0'||c>'9');
do
{
x=x*10+c-'0';
c=getchar();
}while(c>='0'&&c<='9');
return f*x;
}
ll min(ll a,ll b)
{
return a<b?a:b;
}
ll max(ll a,ll b)
{
return a>b?a:b;
}
/**********/
#define MAXN 100011
ll a[MAXN];
int main()
{
ll n=read();
for(ll i=1;i<=n;++i)a[i]=read();
std::sort(a+1,a+n+1);
if(a[n]>=a[n-1]+a[n-2])
{
std::cout<<"NO";
}
else
{
std::cout<<"YES"<<std::endl;
std::swap(a[n],a[n-1]);
for(ll i=1;i<=n;++i)std::cout<<a[i]<<" ";
}
return 0;
}
C. Candies!
题意:对于一个序列 a 1 , a 2 , a 3 . . . a 2 k a_1,a_2,a_3...a_{2^k} a1,a2,a3...a2k,将 ( a