题目
题解
写在前面(牢骚&废话&一丢丢总结):
不好好打场比赛都不知道自己到底有多菜 . 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题
这题对位运算考察不算难,都是些很基础的东西,对于萌新是道好题
通过观察不难发现该函数有这样的性质: ( 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
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
#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
一句话题意:你可以对给定的序列进行无限次操作:选一个区间,使得该区间的所有数变成该区间的平均数,求操作后字典序最小的序列。
单调栈中存放的数据是有序的,分为单调递增栈和单调递减栈
单调递增栈:数据出栈的序列为单调递增序列
单调递减栈:数据出栈的序列为单调递减序列
注意是出栈序列不是数据存放序列哦,区别于单调队列
通过观察不难发现题目中描述的平均值满足单调递增栈(不减但非严格上升)的特性
单调不减:将序列中的每个数都看成一个长度为 1 1 1 的区间,从左往右弹入栈中。若将要弹入栈中区间的平均值不大于栈顶区间的平均值,就将栈顶区间弹出,与将要弹入的区间合并。将合并后的值弹入栈,可保证栈中值一定非严格上升。
#include
#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;
}