呜呜呜我爆零了呜呜呜ljll
嗯T1T2防爆零的没了呜呜呜
在此纪念可怜的yjz大佬21发AC
太惨了(逃
先来说说我们都有些啥题目吧。。。
T1
嗯,裂开了,当场裂开
我一看!桶排!
然后实现,嗯?嗯!嗯???不对啊,这怎么搞???
第一发
嗯!输出错了!改!
第二发
我%^&*()_)(*&^
嗯。。。
我先调一调awa
嗯!找到了!估计能A了!
这wtm。。。
开T2吧。。。
T2
嗯!大水题!
但是,我仔细一看!
正好n个?????
这。。。
瞬间就想到了一个不需要证明的贪心。。。
然后。。。
标准结局
我太难了
仔细一想,发现排个序就好了。。。
然后又调了亿调,就在比赛结束后一分钟的时候A了
这tm的。。。
我接下来看了看T3。。。
就是一个dp。。。(第一想法)
这。。。
不行啊。
那就试试建图!2-sat!(第二想法)
这条件!我吐了,根本不行。。。
第三想法:炸了
然后一想。。。这绝对是个dp。。。
推了推式子,没搞出来。。。
这就是全部的心路历程。。。
我太难了 唉,开始写正解
T1
其实吧,就是一个排序能解决的事情,但是因为那个k的迷惑,我傻了。
想想排序,其实只要保证每一个字典序的接近就能找到最大值中的最小值了
直接构造 其实就是个贪心。。。
排个序
来自oi-wiki 这就是排序贪心的常见的情况之一
第一种情况
如果s[1]==s[k]
排序完了就能发现这个k与1之间是有联系的,只要他们不相同,因为排序的原因,就能够直接的说明在大的字符串就是s[k]。
问为什么的话,其实就是因为如果我在一个字符串中放这个字符,或者是将一类的字符放到其他的k个字符串中,易证,这个一定是可以在这种情况中最大的。
然后是另一种情况。
如果s[k+1]!=s[n]
那么在这种情况下,k个字符串中的第一个字符都是一样的。字典序的大小完全在于后面的字符串
为了保证这是一个最大的字符串,我不得不把下一个字符放在这个字符串上面。
只有这样,才能保证这个是最大中的最小。为了最大,我们一定要在他的后面加入一个字符,但是为了最小,又只能加入全部的字符。
比如对于
5 2 baacb
这个样例就是这种情况。排序完是aabbc,最终的答案是abbc。
最开始,我很疑惑。。。因为我觉得abc<abbc,然后我就傻了。。。
但是在这种情况中,因为必须加入一个字符并最小,所以就会选择加入s[k+1].
这个是很显然的。但是,之后为了使它继续保持在最大的情况下,我们不得不把全部比第一个字符大的字符加入它。
因为如果有一个字符串得到了之后的字符,它就不会再这种情况中继续保持最大了。像abb和ac,ac就会大于abb了。
因为大的字符越靠前,这个字符串的字典序就会越大,所以我们就要尽可能的把大的字符往后靠,也就是把小的字符往前填。
所以就可以得到了awa
第三种情况
就是s[i]==s[k]&&s[k+1]==s[k]
那就之间把第一个输出了,然后在选择几个字符输出就好了啊。。。这是最简单的。
附上代码
#include<bits/stdc++.h> #define ll long long using namespace std; char s[1000001]; int k,n,T; inline ll read() { char c=getchar();ll a=0,b=1; for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1; for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48; return a*b; } int main() { // freopen(".in","r",stdin); // freopen(".out","w",stdout); T=read(); while(T--) { cin>>n>>k; scanf("%s",s+1); sort(s+1,s+n+1); if(s[k]!=s[1]) { printf("%c ",s[k]); } else if(s[n]!=s[k+1]) { printf("%c%s ",s[1],s+k+1); } else { cout<<s[1]; for(int i=1;i<=(n-1)/k;i++) { printf("%c",s[k+1]); } cout<<endl; } } return 0; }
就是这么简单
T2
一看T2,无解输出-1,嗯,要记得,嗯。
然鹅!根本就没有无解的情况。。。极其可怕awa,来自cf的一波误导awa
转载于luogu的题解
要达到最少次数,贪心的想每次肯定加上最多的量 x * 2,然而每次最少加上变化过的x,所以最后一次加的数可能小于当前的x,但是没关系,可以让这次加上的那个小于x的数尽可能的往前移直到前一个数小于等于它,然后按照顺序求一遍答案即可。
这题比T1简单。。。
溜了,附上代码
void solve() { int n; scanf("%d", &n); vector<int> v; int x = 1; while(n > 0) { if(n > x) v.push_back(x); else v.push_back(n); n -= x; x <<= 1; } sort(v.begin(), v.end()); printf("%d ", v.size() - 1); for(int i = 1; i < v.size(); i++) { printf("%d ", v[i] - v[i - 1]); } puts(""); }
T2就好了。。
T3还没写awa
qwq