题目
题解
写在前面(牢骚&废话&一丢丢总结):
不好好打场比赛都不知道自己到底有多菜
.
j
p
g
.jpg
.jpg
第一次打
C
o
d
e
f
o
r
c
e
s
Codeforces
Codeforces就掉
R
a
t
i
n
g
Rating
Rating祭
一开始因为操作不熟和网站太慢,别人都快做完前两道题了才开始做,第一次提交的时候语言没调对还没反应过来愣是
C
E
CE
CE了三次
估计刷新了
O
I
OI
OI界低级错误的sb程度
A
A
A题这种难度的题都想了一段时间
(
(
(前面总是进不去比赛心态崩塌导致做第一题的时候是慌的
)
)
),遇到一点点问题就慌张这毛病啥时候才能改啊暴风哭泣
B
B
B题倒是一眼看出结论在五分钟之内过了
…
\dots
…
C
C
C题把
O
R
OR
OR看成
X
O
R
XOR
XOR,于是第一反应
T
r
i
e
Trie
Trie树
+
+
+贪心
…
\dots
…我没救啦,位运算也掌握得超级不熟,于是开心没搞出来。
C
C
C题都搞不出来我到底是什么超级傻瓜
至于
D
D
D
E
E
E,这个得怪英语太差,赛后好好翻译了一下感觉比
C
C
C题可做
综上,临场心态不够,英语水平太差,位运算基本操作不熟,多打几次比赛好好提升一下啦啦啦
定个小目标:蓝名
A A A题 略过
B B B题 略过
C C C题
Anu Has a Function
这题对位运算考察不算难,都是些很基础的东西,对于萌新是道好题
通过观察不难发现该函数有这样的性质:
(
a
∣
b
)
−
b
=
a
&
(
−
b
)
(a|b)-b = a\&(-b)
(a∣b)−b=a&(−b)。那么题目式子就可以写成
a
1
&
(
∼
a
2
)
&
(
∼
a
3
)
&
…
&
(
∼
a
n
−
1
)
&
(
∼
a
n
)
a_1\&(\thicksim a_2)\&(\thicksim a_3)\&\dots\&(\thicksim a_{n-1})\&(\thicksim a_n)
a1&(∼a2)&(∼a3)&…&(∼an−1)&(∼an),于是发现,影响结果的因素只有第一个元素
(
(
(后面交换顺序得到的结果不变
)
)
),于是显然:只有当某一位上
1
1
1的个数为
1
1
1时,才能对答案产生正向贡献。
做法:枚举每一个数,看是否满足要求,满足就排在前面即可。
代码:注意最后输出
#include <bits/stdc++.h>
using namespace std;
const int N=(int)1e6+5;
int n,a[N],ans,now,sum,vis;
int v[N],b[N][32];
queue<int> q;
inline int read(){
int cnt=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-f;c=getchar();}
while(isdigit(c)){cnt=(cnt<<3)+(cnt<<1)+(c^48);c=getchar();}
return cnt*f;
}
int main(){
n=read();
for(int i=1;i<=n;++i){
a[i]=read();
for(int j=0;j<=31;++j){
b[i][j]=(a[i]>>j)&1;
}
}
for(int i=31;i>=0;--i){
sum=0;
for(int j=1;j<=n;++j){
if(b[j][i]&1){
sum++;vis=j;
}
}
if(sum==1&&v[vis]==0){
q.push(a[vis]);v[vis]=1;
}
}
cerr<<q.size()<<endl;
for(int i=q.size()-1;i>=0;i--){//输出一定要注意循环变量的处理
printf("%d ",q.front());
q.pop();
}
for(int i=1;i<=n;i++){
if(v[i]==0){
printf("%d ",a[i]);
}
}
return 0;
}
/*
5
809571641 29322377 935888946 833709370 2457463
answer:935888946 833709370 29322377 809571641 2457463
*/
D
D
D题
1299
B
−
A
e
r
o
d
y
n
a
m
i
c
1299B - Aerodynamic
1299B−Aerodynamic
一句话题意:判断两个多边形是否相似
完整题目戳这里
题读了三遍依然不知道它要求什么,看来首先需要提升的是英语
我怎么连题解也看不懂
通过向量坐标表示的各种性质可以发现
P
P
P就是对边平行且相等的偶数边形,容易发现这是中心对称的,不难证明
(
(
(其实是我不会,貌似可以用闵可夫斯基和来证
)
)
)只要
P
P
P中心对称,
P
P
P和
T
T
T一定相似。
问题转化为判定
P
P
P是否合法
比较是否合法:比较对应的两个点中点是否合法
中点:图形对称中心
#include <bits/stdc++.h>
#define db double
using namespace std;
const int N=(int)1e5+50;
int n;
struct node{
db x,y;
}a[N],st,ed,pnt1,pnt2;
inline int read(){
int cnt=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-f;c=getchar();}
while(isdigit(c)){cnt=(cnt<<3)+(cnt<<1)+(c^48);c=getchar();}
return cnt*f;
}
bool isok(node st,node ed){
if(st.x!=ed.x||st.y!=ed.y)return false;
return true;
}
int main(){
n=read();
for(int i=1;i<=n;++i){
a[i].x=read(),a[i].y=read();
}
if(n%2==1){printf("NO");return 0;}
int p=n/2;
st.x=(a[1].x+a[p+1].x)*1.0/2;
st.y=(a[1].y+a[p+1].y)*1.0/2;
for(int i=2;i<=p;++i){
ed.x=(a[i].x+a[p+i].x)*1.0/2;
ed.y=(a[i].y+a[p+i].y)*1.0/2;
if(!isok(st,ed)){printf("NO");return 0;}
}
printf("YES");
return 0;
}
E
E
E题
W
a
t
e
r
B
a
l
a
n
c
e
Water Balance
WaterBalance
一句话题意:你可以对给定的序列进行无限次操作:选一个区间,使得该区间的所有数变成该区间的平均数,求操作后字典序最小的序列。
s o e a s y の so\ easyの so easyの前置知识单调栈
单调栈中存放的数据是有序的,分为单调递增栈和单调递减栈
单调递增栈:数据出栈的序列为单调递增序列
单调递减栈:数据出栈的序列为单调递减序列
注意是出栈序列不是数据存放序列哦,区别于单调队列
通过观察不难发现题目中描述的平均值满足单调递增栈(不减但非严格上升)的特性
单调不减:将序列中的每个数都看成一个长度为
1
1
1 的区间,从左往右弹入栈中。若将要弹入栈中区间的平均值不大于栈顶区间的平均值,就将栈顶区间弹出,与将要弹入的区间合并。将合并后的值弹入栈,可保证栈中值一定非严格上升。
#include <bits/stdc++.h>
#define ll long long
#define db double
using namespace std;
const int N=(int)1e6+50;
int n,len,a[N];
struct node{
int l,r;
ll val;
};
vector<node> sta;
inline ll read(){
ll cnt=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-f;c=getchar();}
while(isdigit(c)){cnt=(cnt<<3)+(cnt<<1)+(c^48);c=getchar();}
return cnt*f;
}
int main(){
n=read();
for(int i=1;i<=n;++i){a[i]=read();}
sta.push_back({1,1,a[1]});
for(int i=2;i<=n;++i){
sta.push_back({i,i,a[i]});
//单调栈的实现
while(sta.size()>=2){
len=sta.size();
db aver1=1.0*sta[len-1].val/(sta[len-1].r-sta[len-1].l+1);
db aver2=1.0*sta[len-2].val/(sta[len-2].r-sta[len-2].l+1);
if(aver1<=aver2){
sta.pop_back();sta.pop_back();
sta.push_back({sta[len-2].l,sta[len-1].r,sta[len-1].val+sta[len-2].val});
}
else break;
}
}
for(int i=0;i<sta.size();++i){
db aver=1.0*sta[i].val/(sta[i].r-sta[i].l+1);
for(int j=sta[i].l;j<=sta[i].r;++j){
printf("%.9lf\n",aver);
}
}
return 0;
}