比赛链接:Codeforces Round #618 (Div.1)
A. Anu Has a Function
题意:给出n个数的排列,使得题给表达式的值最大;
分析:将所有数转成二进制,一旦某个位置有多个数都为1,那么该位置在最终答案一定为0,因此,答案取决于只有一个数在某个位置为1的情况,贪心的令这个位置尽可能高,把它定为第一个(因为第一个不会减掉这个位置的1),如果不存在这样的位置,随便什么顺序都可以,因为都会被减掉;
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn=1e5+7;
const int mod=1e9+7;
const ll INF=1e18;
int a[maxn],tag[50],mp[50];
int main()
{
int n;scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
int x=a[i],res=0;
while(x)
{
if(x&1) tag[res]++,mp[res]=a[i];
x>>=1;res++;
}
}
int ff=-1;
for(int i=0;i<=31;i++) if(tag[i]==1) ff=mp[i];
if(ff==-1) for(int i=1;i<=n;i++) printf("%d ",a[i]);
else
{
printf("%d",ff);
for(int i=1;i<=n;i++) if(a[i]!=ff) printf(" %d",a[i]);
}
}
B. Aerodynamic
题意:给你一个n边形,平移n次这个多边形使得,使得每个顶点都到达原点,保留剩下的n-1个点,问保留的这些点组成的多边形能否和原多边形相似;
分析:判定多边形是否中心对称(自己画一下就能感受到);
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn=1e5+7;
const int mod=1e9+7;
const ll INF=1e18;
int x[maxn],y[maxn];
struct node{int a,b;} p[maxn];
int main()
{
int n;scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]);
x[n+1]=x[1];y[n+1]=y[1];
if(n%2==1) {printf("No\n");return 0;}
for(int i=1;i<=n/2;i++) p[i]={x[i+1]-x[i],y[i+1]-y[i]};
for(int i=n/2+1;i<=n;i++) p[i]={x[i]-x[i+1],y[i]-y[i+1]};
int ff=1;
for(int i=1;i<=n/2;i++)
if(p[i].a!=p[i+n/2].a || p[i].b!=p[i+n/2].b) {ff=0;break;}
if(ff) printf("Yes\n");
else printf("No\n");
return 0;
}
C. Water Balance
题意:给你n个数,你可以无限次的任意选取一段区间,区间内的每一个数都改成区间和的平均值,问你最终得到的字典序最小的n个数是什么(字典序最小指前面的数尽可能小);
分析:维护一个单调栈,栈内元素是答案序列中出现的数(从小到大);具体操作就是:每次读入一个数并插入栈顶,可以把下面的元素改小时一直向下合并,就是说如果我比下面的元素小,我就去改小它,改到不能再改;
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn=1e6+7;
const int mod=1e9+7;
const ll INF=1e18;
double sta[maxn];
int num[maxn];
int main()
{
int n,top=0;scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int x;scanf("%d",&x);
sta[++top]=x;num[top]=1;
while(top>1 && sta[top]<=sta[top-1])
{
top--;
sta[top]=(sta[top]*num[top]+sta[top+1]*num[top+1])/(num[top]+num[top+1]);
num[top]+=num[top+1];num[top+1]=0;
}
}
for(int i=1;i<=top;i++) while(num[i]--) printf("%.10f\n",sta[i]);
return 0;
}