题目链接
南北对决-美团2023笔试(codefun2000)
题目内容
南派北派武林大会开始了。本次攻擂赛有 n 名武者参加,其中按顺序第 i 名武者获得战斗力属性为 i 。每名武者分来自南派或者北派。如果不同派系的武者在擂台上相遇,战斗力属性值大的获得胜利,如果同派系的武者在擂台上相遇,强者会相让弱者,战斗力属性值小的会获得胜利。参加战斗的所有武者两两都会进行一场决斗,请你计算出每名武者获胜的次数。
输入描述
输出描述
对于每组数据,输出一行,包括 n 个整数,每个整数表示每个人能赢多少场。
样例1
输入
3
9
0 0 1 0 0 1 0 0 1
6
1 1 0 1 1 0
4
1 0 0 0
输出
5 4 4 4 3 5 3 2 6
3 2 3 2 1 4
0 3 2 1
题解1
// 前缀和
#include<bits/stdc++.h>
using namespace std;
const int N = 5e4+10;
int t, n, a[N], pre[N], ans[N];
/* 如果a[i]=1,则第i名武者获胜的次数 = 区间[1,i-1]中0的个数+区间[i+1,n]中1的个数
如果a[i]=0,则第i名武者获胜的次数 = 区间[1,i-1]中1的个数+区间[i+1,n]中0的个数
*/
int main(){
scanf("%d", &t);
while(t--){
memset(pre, 0, sizeof pre);
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]), pre[i] = pre[i - 1] + a[i];
for(int i = 1; i <= n; i++){
if(a[i] == 1) ans[i] = (i - 1) - pre[i - 1] + (pre[n] - pre[i]);
else ans[i] = pre[i - 1] + ((n - i) - (pre[n] - pre[i]));
}
for(int i = 1; i <= n; i++){
if(i > 1) printf(" ");
printf("%d", ans[i]);
}
printf("\n");
}
return 0;
}