Codeforces1300(618Round Div2)

题目
题解
写在前面(牢骚&废话&一丢丢总结):
不好好打场比赛都不知道自己到底有多菜 . 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

这题对位运算考察不算难,都是些很基础的东西,对于萌新是道好题
Codeforces1300(618Round Div2)_第1张图片
通过观察不难发现该函数有这样的性质: ( a ∣ b ) − b = a & ( − b ) (a|b)-b = a\&(-b) (ab)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)&&(an1)&(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 1299BAerodynamic
一句话题意:判断两个多边形是否相似
完整题目戳这里
题读了三遍依然不知道它要求什么,看来首先需要提升的是英语
我怎么连题解也看不懂
通过向量坐标表示的各种性质可以发现 P P P就是对边平行且相等的偶数边形,容易发现这是中心对称的,不难证明 ( ( (其实是我不会,貌似可以用闵可夫斯基和来证 ) ) )只要 P P P中心对称, P P P T T T一定相似。
问题转化为判定 P P P是否合法
Codeforces1300(618Round Div2)_第2张图片
比较是否合法:比较对应的两个点中点是否合法
中点:图形对称中心

#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
一句话题意:你可以对给定的序列进行无限次操作:选一个区间,使得该区间的所有数变成该区间的平均数,求操作后字典序最小的序列。
Codeforces1300(618Round Div2)_第3张图片
Codeforces1300(618Round Div2)_第4张图片

s o   e a s y の so\ easyの so easy前置知识单调栈

单调栈中存放的数据是有序的,分为单调递增栈和单调递减栈
单调递增栈:数据出栈的序列为单调递增序列
单调递减栈:数据出栈的序列为单调递减序列
注意是出栈序列不是数据存放序列哦,区别于单调队列

通过观察不难发现题目中描述的平均值满足单调递增栈(不减但非严格上升)的特性
单调不减:将序列中的每个数都看成一个长度为 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;
}

你可能感兴趣的:(Codeforces)