感觉这场还挺顺的,就是网有点卡....然后就是死磕D没磕出来....
Codeforces Round #773 (Div. 2)
A. Hard Way
这个题是真的很难读懂题....
题意:给定一个三角形,问这个三角形那些线段是在x轴上从某个点出发到达不了的。到达的定义为:从一个点出发沿着一个方向延伸,图中不能经过这个三角形的其他边。
很容易发现只有当某个三角形一条边与x轴平行且剩下一个点在这条边下方时,才无法到达。
B. Power Walking
题意:我们要将n个饼干分给k个小朋友,饼干有它的种类,每个小朋友至少得有一个饼干并且一个小朋友的开心度为他收到的饼干的种类。问对于k从1-n,小朋友的开心度和最小依次为多少?
比较贪心的思想就是对于一个小朋友我们只将相同种类的饼干分给他。我们统计出n个饼干的总的种类t。若k<t的话,答案为t,我们的方案就是每个小朋友给一种种类的饼干,之后剩下的饼干给最后一个小朋友即可。若k>=t,则答案为t.
C. Great Sequence
这个题就很简单了,我们将能配对的配对,不能配对的只能添加一个数使它配对。
D. Repetitions Decoding
这个题要求你添加若干个重复的数(22,33,xx,)之类的,然后将这个序列分成若干段,使得每一段由相等的两部分组成...
我的想法就是从前到后依次构造,然后有相同的两部分之后将他们消掉即可。一直在考虑怎么将第一段摘出,然后将第一段补全和后面的一起消掉,也考虑过将一个单独的元素放到一个单独的部分,但离正确的做法还差一点...
同样的也是找到第一个成对的数字,例如:1231,那我们将123作为第一部分,将剩下的1作为第二部分,之后我们只需要在1后面复刻23,即可,通过这样的操作,虽然我们第二部分增加了32,但我们却把1消掉了,考虑我们最多的操作次数,每两个数都可能有n次操作,那最多的操作次数就是nn/2。不懂题目为什么将次数控制到2n^2,这么多....
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=510,M=500010;
int T,n,a[N],b[M],num,c[M],cnt,p[M];
map<int,int>mp;
deque<int>q1,q2;
inline bool check()
{
for(auto x:mp) if(x.second%2==1) return false;
return true;
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
mp.clear();num=0;cnt=0;
for(int i=1;i<=n;++i) scanf("%d",&a[i]),mp[a[i]]++;
if(!check()) {puts("-1");continue;}
q1.clear();q2.clear();
for(int i=1;i<=n;++i) q2.push_back(a[i]);
int r=1;
while(q2.size())
{
q1.push_back(q2.front());
q2.pop_front();++r;
while(q2.front()!=q1.front())
{
q1.push_back(q2.front());
q2.pop_front();++r;
}
++cnt;
while(q1.size())
{
if(q2.size()&&q1.front()==q2.front())
{
q1.pop_front();
q2.pop_front();
c[cnt]+=2;++r;
}
else
{
b[++num]=r-1;
p[num]=q1.front();
q2.push_front(q1.front());
q2.push_front(q1.front());
}
}
}
printf("%d\n",num);
for(int i=1;i<=num;++i) printf("%d %d\n",b[i],p[i]);
printf("%d\n",cnt);
for(int i=1;i<=cnt;++i) printf("%d ",c[i]),c[i]=0;
puts("");
}
return 0;
}