CF 549G swap(前-1,后+1),问是否能变成递增序列(灵活题)

本文探讨了一种策略,帮助Berland的居民通过交换位置来确保每个人都能感到快乐。在这个炎热的夏天,居民们排起了长队等待购买冰淇淋。他们通过互相交换位置来调整队伍顺序,使得每个人都拥有至少与前一人相同数量的钱币。文章详细介绍了如何通过数学方法解决这一问题,并提供了示例代码来验证解决方案的有效性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Do you like summer? Residents of Berland do. They especially love eating ice cream in the hot summer. So this summer day a large queue of n Berland residents lined up in front of the ice cream stall. We know that each of them has a certain amount of berland dollars with them. The residents of Berland are nice people, so each person agrees to swap places with the person right behind him for just 1 dollar. More formally, if person astands just behind person b, then person a can pay person b 1 dollar, then a and b get swapped. Of course, if person a has zero dollars, he can not swap places with person b.

Residents of Berland are strange people. In particular, they get upset when there is someone with a strictly smaller sum of money in the line in front of them.

Can you help the residents of Berland form such order in the line so that they were all happy? A happy resident is the one who stands first in the line or the one in front of who another resident stands with not less number of dollars. Note that the people of Berland are people of honor and they agree to swap places only in the manner described above.

Input

The first line contains integer n (1 ≤ n ≤ 200 000) — the number of residents who stand in the line.

The second line contains n space-separated integers ai (0 ≤ ai ≤ 109), where ai is the number of Berland dollars of a man standing on the i-th position in the line. The positions are numbered starting from the end of the line.

Output

If it is impossible to make all the residents happy, print ":(" without the quotes. Otherwise, print in the single line n space-separated integers, the i-th of them must be equal to the number of money of the person on position i in the new line. If there are multiple answers, print any of them.

Sample test(s)
input
2
11 8
output
9 10 
input
5
10 9 7 10 6
output
:(
input
3
12 3 3
output
4 4 10 
Note

In the first sample two residents should swap places, after that the first resident has 10 dollars and he is at the head of the line and the second resident will have 9 coins and he will be at the end of the line.

In the second sample it is impossible to achieve the desired result.

In the third sample the first person can swap with the second one, then they will have the following numbers of dollars: 4 11 3, then the second person (in the new line) swaps with the third one, and the resulting numbers of dollars will equal to: 4 4 10. In this line everybody will be happy.

http://codeforces.com/problemset/problem/549/G

这题我是用能量守恒的方法考虑的。请先看一眼代码——开始的时候依次加了i,最后依次减去i,也就是说,数组的总和还是不变的。+i是为了使中间过程形成递增。

x[i]==x[i-1],假设可以,那么下面输出序列就是 x[i-1]-(i-1) > x[i]-i ,明显不可以。

#include <set>
#include <map>
#include <queue>
#include <cmath>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int x[200010];
int main(){
	int n;
	cin>>n;
	for(int i=0;i<n;++i){
		cin>>x[i];
		x[i]+=i;
	}
	sort(x,x+n);
	for(int i=1;i<n;++i){
		if(x[i]==x[i-1]){
			cout<<":(";
			return 0;
		}
	}
	for(int i=0;i<n;++i)
		cout<<x[i]-i<<" ";
	return 0;
}


#include <stdio.h> #include <stdlib.h> #define OK 1 #define OVERFLOW -1 #define ERROR 0 typedef int Status; /* 二叉树的链式存储表示 */ typedef char TElemType; /* 由用户定义的实际数据类型 */ typedef struct BiTNode { TElemType data; struct BiTNode* lchild, * rchild; /* 左右孩子指针 */ } BiTNode, * BiTree; /* 结点类型 */ /* 函数声明 */ void CreateBiTree(BiTree* T); /* 构造二叉链表 */ Status PrintChar(TElemType e); /* Visit 函数 */ Status PreOrderTraverse(BiTree T, Status(*Visit)(TElemType e)); /* 序遍历二叉树 */ void InOrderTraverse(BiTree T); /* 中序遍历二叉树 */ void PostOrderTraverse(BiTree T); /* 后序遍历二叉树 */ int nodes(BiTree T); /* 计算总结点数 */ int leafs(BiTree T); /* 计算总叶子数 */ int depth(BiTree T); /* 计算二叉树的深度 */ void swap(BiTree T); /* 交换左右子树 */ void ChangeValue(BiTree T); /* 对二叉树每个结点赋值 */ int main() { BiTree T; int choice; printf("input preorder nodes: (xu jie dian yong kong ge biao shi)\n"); CreateBiTree(&T); do { printf("\n======== 二叉树操作菜单 ===============\n"); printf("1. 序遍历\n"); printf("2. 中序遍历\n"); printf("3. 后序遍历\n"); printf("4. 计算总结点数\n"); printf("5. 计算总叶子数\n"); printf("6. 计算二叉树深度\n"); printf("7. 交换左右子树\n"); printf("8. 对二叉树每个结点赋值\n"); printf("0. 退出程序\n"); printf("=====================================\n"); printf("请输入您的选择:"); scanf_s("%d", &choice); switch (choice) { case 1: printf("序遍历结果:"); PreOrderTraverse(T, PrintChar); printf("\n"); break; case 2: printf("中序遍历结果:"); InOrderTraverse(T); printf("\n"); break; case 3: printf("后序遍历结果:"); PostOrderTraverse(T); printf("\n"); break; case 4: printf("总结点数:%d\n", nodes(T)); break; case 5: printf("总叶子数:%d\n", leafs(T)); break; case 6: printf("二叉树深度:%d\n", depth(T)); break; case 7: swap(T); printf("交换左右子树后的序遍历结果:"); PreOrderTraverse(T, PrintChar); printf("\n"); break; case 8: ChangeValue(T); printf("赋值后的序遍历结果:"); PreOrderTraverse(T, PrintChar); printf("\n"); break; case 0: exit(0); default: printf("输入有误,请重新输入!\n"); } } while (choice != 0); return 0; } /* 构造二叉链表 */ void CreateBiTree(BiTree* T) { char ch; scanf_s(" %c", &ch); /* 注意空格,跳过空白字符 */ if (ch == ' ') *T = NULL; else { if (!(*T = (BiTNode*)malloc(sizeof(BiTNode)))) exit(OVERFLOW); (*T)->data = ch; CreateBiTree(&((*T)->lchild)); CreateBiTree(&((*T)->rchild)); } } Status PrintChar(TElemType e) { /* Visit 函数 */ printf("%c", e); return OK; } /* 序遍历二叉树 */ Status PreOrderTraverse(BiTree T, Status(*Visit)(TElemType e)) { if (T) { if (Visit(T->data)) if (PreOrderTraverse(T->lchild, Visit)) if (PreOrderTraverse(T->rchild, Visit)) return OK; return ERROR; } else return OK; } /* 中序遍历二叉树 */ void InOrderTraverse(BiTree T) { if (T) { InOrderTraverse(T->lchild); printf("%c", T->data); InOrderTraverse(T->rchild); } } /* 后序遍历二叉树 */ void PostOrderTraverse(BiTree T) { if (T) { PostOrderTraverse(T->lchild); PostOrderTraverse(T->rchild); printf("%c", T->data); } } /* 计算总结点数 */ int nodes(BiTree T) { if (T) return (nodes(T->lchild) + nodes(T->rchild) + 1); else return (0); } /* 计算总叶子数 */ int leafs(BiTree T) { if (T == NULL) return (0); else { if (T->lchild == NULL && T->rchild == NULL) return (1); else return (leafs(T->lchild) + leafs(T->rchild)); } } /* 计算二叉树的深度 */ int depth(BiTree T) { int hl, hr, max; if (T) { if (T->lchild == NULL && T->rchild == NULL) return 1; else { hl = depth(T->lchild); hr = depth(T->rchild); max = (hl > hr) ? hl : hr; return max + 1; } } else return 0; } /* 交换左右子树 */ void swap(BiTree T) { BiTree p; if (T) { p = T->lchild; T->lchild = T->rchild; T->rchild = p; swap(T->lchild); swap(T->rchild); } } /* 对二叉树每个结点赋值 */ void ChangeValue(BiTree T) { if (T) { ChangeValue(T->lchild); ChangeValue(T->rchild); if (T->lchild == NULL && T->rchild == NULL) { T->data = 3; } else if (T->lchild == NULL) { T->data = T->rchild->data; } else if (T->rchild == NULL) { T->data = T->lchild->data; } else { T->data = T->lchild->data + T->rchild->data; } } } 该代码在Vs中运行不出来,请用c语言修改,给出一份新的完整代码
最新发布
06-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值