再写题解前,首先得感谢一波AtCode的出题人成功浪费我一上午时间…最后还是不会(Almost Everywhere Zero),感谢哪位大佬赐教…
AB就没有没有什么可说的了,看完题直接写就行!
A. Non-zero
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
map<int,int> mp;
int main()
{
int t;cin>>t;
while(t--)
{
int n; cin>>n;
int a[200];
ll sum=0;
ll cnt=0;
for(int i=0;i<n;i++)
{
cin>>a[i];
if(a[i]==0)
{
a[i]=a[i]+1;
cnt++;
}
sum=sum+a[i];
}
if(!sum)
cout<<cnt+1<<endl;
else
cout<<cnt<<endl;
}
return 0;
}
B. Assigning to Classes
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
map<int,int> mp;
int a[1111111];
int main()
{
int t; cin>>t;
while(t--)
{
int n; cin>>n;
int len=2*n;
for(int i=1;i<=len;i++)
cin>>a[i];
sort(a+1,a+len+1);
cout<<a[n+1]-a[n]<<endl;
}
return 0;
}
C. Anu Has a Function
题意:给一个数组,进行某种排序后,使得 f(f(…f(f(a1,a2),a3),…an−1),an)最大
思路:因为f(1,0)=1,而 f(1,1)=0;f(0,1)=0;f(0,0)=0。所以直接将这个数分解成二进制得到样子,从第最后一位向前找就行了,再处理一下同一个数字有多个的情况就行了,真的是太菜了…就这还写了一个小时还WA掉了…
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N];
int f[N][50];
int flag[N];
int main()
{
int n; cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
for(int j=0;j<32;j++)
{
f[i][j]=(a[i]>>j)&1;
}
}
for(int j=31;j>=0;j--)
{
int sum=0;
int cnt=0;
for(int i=0;i<n;i++)
{
if(f[i][j])
{
sum++;
cnt=i;
}
}
if(sum==1&&!flag[cnt])
{
cout<<a[cnt]<<" ";
flag[cnt]=1;
}
}
for(int i=0;i<n;i++)
if(!flag[i])
cout<<a[i]<<" ";
cout<<endl;
return 0;
}
还有一种题解是可以化成x&(-y)…有兴趣可以试试。
D. Aerodynamic
直接盗取舍友的博客23333…
题意:
题意很长,就是给一个多边形P,然后P在原点附近平移(保证原点在P的内部或者边上),然后P移动的区域是多边形T,然后问P和T是否相似?
思路:
只有当P的顶点个数是偶数并且P是中心对称图形时才满足题意;
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+7;
struct node
{
double x,y;
}bb[N];
int main()
{
int n;
cin >>n;
for(int i=1;i<=n;i++)
{
cin >>bb[i].x>>bb[i].y;
}
int flag=1;
if(n%2==1)
{
flag=0;
}
else
{
int j=n/2;
double x=(bb[1].x+bb[1+j].x)/2,y=(bb[1].y+bb[1+j].y)/2;
for(int i=2;i<=n/2;i++)
{
if((bb[i].x+bb[i+j].x)/2!=x||(bb[i].y+bb[i+j].y)/2!=y)
{
flag=0;
break;
}
}
}
if(flag) cout <<"YES"<<endl;
else cout <<"NO"<<endl;
}
E. Water Balance
题意:就是把某个区间的数字都变成这个区间数字和的平均数,可以操作多次,问最小的字典序。
思路:这个题还是挺好想的。假如有 a b c d e f 这6个数字,前三个数字平均数为A,后三个为平均数B,当你有g这个数字加进来时候,首先得看g和B的关系,假如g<B,那么肯定能把B变得更小,这里记为B1,再比较B1和A的大小,如果B1比A小,那么就可以合并成一个更大的区间。就这样不断加不断维护就行,直接看代码吧。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+7;
double a[N],len[N],st[N];
int main()
{
int n,p=0; cin>>n;
for(int i=1;i<=n;i++)
scanf("%lf",&a[i]);
for(int i=1;i<=n;i++)
{
st[++p]=a[i];
len[p]=1;
while(p>1&&st[p]<st[p-1])
{
st[p-1]=(st[p]*len[p]+st[p-1]*len[p-1])/(len[p]+len[p-1]);
len[p-1]=len[p-1]+len[p];
p--;
}
}
for(int i=1;i<=p;i++)
for(int j=1;j<=len[i];j++)
printf("%.12f\n",st[i]);
cout<<endl;
return 0;
}