南北对决-美团2023笔试(codefun2000)

题目链接
南北对决-美团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;
}
  • 12
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值