cf round#510 div2 C-Array Product 逻辑规律

有两种操作

1操作  格式:1  i  j    然后把i*j的结果 放在第j个数  第i个数删除

2操作  格式:   2  i       把第i个数删除      且最多只能用一次操作2

题目给你n个数   然后输出这些操作方案 使得n个数最后只剩一个数  这个数需要最大

思路:很容易想到   0的个数   负数的个数  是解题关键

既然是个数  那就有 奇偶 之分

大概都会想到 负数是奇的话  去掉       偶数就直接乘  负负得正嘛

尽可能把0去掉    如何尽可能  进行1操作  我这称为“合0”   然后多个0就会变成一个0了  最后再“去0”

注意奇数是什么   num%2 == 1   那1  也是  但是1个你不能去掉呀  去了就没数了  

扫描二维码关注公众号,回复: 3353221 查看本文章

注意全0  我进行“合0”之后  只剩1个了 这个情况也不能去呀

#include <bits/stdc++.h>

using namespace std;

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif
	
	int n;
	scanf("%d", &n);
	vector<int> a(n);//vector() 可以动态申请空间 
	for (int i = 0; i < n; ++i)
		scanf("%d", &a[i]);
	
	int cntneg = 0;
	int cntzero = 0;
	vector<int> used(n);
	int pos = -1;
	for (int i = 0; i < n; ++i) {
		if (a[i] == 0) {
			used[i] = 1;
			++cntzero;
		}
		if (a[i] < 0) {
			++cntneg;
			if (pos == -1 || abs(a[pos]) > abs(a[i]))
				pos = i;//保存最大负数
		}
	}
	if (cntneg & 1)//如果负数个数 是奇数
		used[pos] = 1;//那么这个奇数也要操作
		
	// 全是0的情况  或 一个负数 其余都是0的情况 合并所有0后 再合并这个负数 变0了  
	//不用删除 
	if (cntzero == n || (cntzero == n - 1 && cntneg == 1)) {
		for (int i = 0; i < n - 1; ++i)
			printf("1 %d %d\n", i + 1, i + 2);
		return 0;
	}
	
	int lst = -1;
	for (int i = 0; i < n; ++i) {
		if (used[i]) {
			if (lst != -1) printf("1 %d %d\n", lst + 1, i + 1);
			lst = i;//找到两个才输出
		}
	}
	if (lst != -1) printf("2 %d\n", lst + 1);//最后还要删除0 和 最大负数的产物
	
	//然后就是剩下的数 操作1
	lst = -1;
	for (int i = 0; i < n; ++i) {
		if (!used[i]) {
			if (lst != -1) printf("1 %d %d\n", lst + 1, i + 1);
			lst = i;
		}
	}
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/liangnimahanwei/article/details/82820596
今日推荐