题目来源:https://codeforces.com/contest/1300
D题猜的,不过我觉得猜的挺有道理的233
发现E题真的不是很难(码量不大),但是就是想不到…
A - Non-zero
多判断几下 应该不难
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=2e5+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
int f[N];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
int t;
r(t);
while(t--){
r(n);
LL sum=0;
int cnt=0;
LL ans=0;
FOR(i,1,n){
r(f[i]);
sum+=f[i];
if(f[i]==0) cnt++;
}
if(cnt!=0){
ans+=cnt;
if(sum+cnt==0) ans++;
}
else if(sum==0){
bool flag=1;
FOR(i,1,n){
if(f[i]!=-1) flag=0;
}
if(flag) ans+=2;
else ans++;
}
cout<<ans<<endl;
}
return 0;
}
B - Assigning to Classes
就排个序 取中间两个值的差就好了
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=2e5+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
int f[N];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
int t;
r(t);
while(t--){
r(n);
FOR(i,1,2*n) r(f[i]);
sort(f+1,f+n*2+1);
cout<<f[n+1]-f[n]<<endl;
}
return 0;
}
C - Anu Has a Function
我太憨了,居然用线段树写,其实一个前缀or一个后缀or就够了。
就是很容易发现,其实这个最终值只和第一个的值有关,我们就枚举第一个是哪个数(假如是x),然后其他的数的or 假如是y ,那这种情况的结果就是 x-(x&y) 注意优先级 要打括号,怎么求除这个数之外的or呢?两个前缀和,别像我一样用线段树,杀鸡焉用牛刀…
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=2e5+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
int f[N];
int sum[N<<2];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
void build(int k,int l,int r)
{
if(l==r){
sum[k]=f[l];
return ;
}
int mid=(l+r)>>1;
build(ls); build(rs);
sum[k]=sum[k<<1]|sum[k<<1|1];
}
int query(int k,int l,int r,int x,int y)
{
if(x<=l&&r<=y){
return sum[k];
}
int mid=(l+r)>>1;
int res=0;
if(mid>=x) res|=query(ls,x,y);
if(mid<y) res|=query(rs,x,y);
return res;
}
int main()
{
int t;
r(n);
int pos=0;
FOR(i,1,n){
r(f[i]);
}
build(1,1,n);
int maxx=-1;
FOR(i,1,n){
int now=0;
if(i>1) now|=query(1,1,n,1,i-1);
if(i<n) now|=query(1,1,n,i+1,n);
//cout<<f[i]<<' '<<now<<endl;
int res=f[i]-(f[i]&now);
//cout<<res<<endl;
if(maxx<res){
pos=i;
maxx=res;
}
}
cout<<f[pos];
FOR(i,1,n){
if(i!=pos) cout<<' '<<f[i];
}
cout<<endl;
return 0;
}
D - Aerodynamic
这题题目看了40分钟…
猜的结论:要有偶数个点,其次对边要平行且相等
判断的话用向量判断最好不过了,少了精度的干扰。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=2e5+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
struct point
{
LL x,y;
}f[N];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
double dis(point p1,point p2)
{
}
int main()
{
r(n);
FOR(i,1,n){
r(f[i].x); r(f[i].y);
}
f[n+1]=f[1];
bool flag=1;
if(n&1){
cout<<"NO\n";
return 0;
}
FOR(i,1,n/2){
point p1=f[i],p2=f[i+1],p3=f[i+n/2],p4=f[i+n/2+1];
if(p2.x-p1.x==p3.x-p4.x&&p2.y-p1.y==p3.y-p4.y){
flag=1;
}
else{
flag=0;
break;
}
}
if(flag) cout<<"YES\n";
else cout<<"NO\n";
return 0;
}
E - Water Balance
思路就是从左到右扫,每次将一个点加进去 和前面的比较 如果当前的点小,那就可以和前一个合并 让前一个变小,用栈实现都可以,我手动写栈是因为 stack不好输出233
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<double,int> pt;
const int N=1e6+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=998244353;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
int f[N];
pt ans[N];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
r(n);
FOR(i,1,n) r(f[i]);
int cnt=0;
ans[++cnt]=mp(f[1],1);
FOR(i,2,n){
if(f[i]<ans[cnt].first){
double res=(ans[cnt].first*ans[cnt].second+f[i])*1.0/(ans[cnt].second+1);
ans[cnt]=mp(res,ans[cnt].second+1);
while(cnt>=2&&ans[cnt].first<ans[cnt-1].first){
res=(ans[cnt].first*ans[cnt].second+ans[cnt-1].first*ans[cnt-1].second)*1.0/(ans[cnt].second+ans[cnt-1].second);
ans[--cnt]=mp(res,ans[cnt].second+ans[cnt-1].second);
}
}
else ans[++cnt]=mp(f[i],1);
}
FOR(i,1,cnt){
FOR(j,1,ans[i].second) printf("%.9f\n",ans[i].first);
}
cout<<endl;
return 0;
}