Codeforces Round #618 (Div. 2)题解
A. Non-zero
思路:如果数组中有0,那么乘积肯定为0,因此我们只要统计0的个数,给每个0加上1即可,之后还需考虑给所有0机上1和为0的情况,此时要再加上1
#include<iostream> #include<algorithm> using namespace std; int main() { int t; cin>>t; while(t--){ int n,x,sum=0,cnt=0; cin>>n; for(int i=1;i<=n;i++){ cin>>x; if(x==0) cnt++; sum+=x; } if(cnt+sum==0) cnt++; cout<<cnt<<endl; } return 0; }
B. Assigning to Classes
思路:排序后直接输出a[n+1]-a[n]即可,证明略
#include<iostream> #include<algorithm> using namespace std; const int maxn=2e5+5; int a[maxn]; int main() { int t; cin>>t; while(t--){ int n; scanf("%d",&n); for(int i=1;i<=2*n;i++) scanf("%d",&a[i]); sort(a+1,a+1+2*n); cout<<(a[n+1]-a[n])<<endl; } }
C. Anu Has a Function
思路:(x|y)-y ==x&(-y) ,经过每次操作只会留下x为1,y不为1的部分,所以最优的策略就是将所有数中二进制从左到右扫过出现的第一个只有这个数的1位为1,其他数为0的数放在第一个,其他书随意排序即可
#include<iostream> #include<algorithm> using namespace std; const int maxn=1e5+20; typedef long long ll; ll a[maxn]; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); for(int i=32;i>=0;i--){ int cnt=0,pos=-1; for(int j=1;j<=n;j++){ if((a[j]>>i)&1) cnt++,pos=j; } if(cnt==1){ cout<<a[pos]; for(int j=1;j<=n;j++) if(j!=pos) cout<<" "<<a[j]; return 0; } } for(int i=1;i<=n;i++) cout<<a[i]<<" "; return 0; }
D. Aerodynamic
思路:猜出的结论,是要判断是否为中心对称图形即可
#include<algorithm> #include<iostream> using namespace std; struct V{ double x,y; }v[300000+5]; int main(){ int n,flag=1; scanf("%d",&n); for(int i=0;i<n;i++) cin>>v[i].x>>v[i].y; int tx=v[0].x+v[n/2].x,ty=v[0].y+v[n/2].y; int i; for(i=1;i<(n+1)/2;i++) { if(v[i].x+v[i+n/2].x!=tx ||v[i].y+v[i+n/2].y!=ty) {flag=0; break;} } if(flag) cout<<"YES\n"; else cout<<"NO\n"; }