codeforces C. Queue

本文探讨了Berland Bank中顾客根据身高及记忆中的前方较高人数进行排队的问题。提出了通过排序和插入策略来重构队伍的方法,并附带了完整的AC代码实现。

In the Main Berland Bank n people stand in a queue at the cashier, everyone knows his/her height hi, and the heights of the other people in the queue. Each of them keeps in mind number ai — how many people who are taller than him/her and stand in queue in front of him.

After a while the cashier has a lunch break and the people in the queue seat on the chairs in the waiting room in a random order.

When the lunch break was over, it turned out that nobody can remember the exact order of the people in the queue, but everyone remembers his number ai.

Your task is to restore the order in which the people stood in the queue if it is possible. There may be several acceptable orders, but you need to find any of them. Also, you need to print a possible set of numbers hi — the heights of people in the queue, so that the numbersai are correct.

Input

The first input line contains integer n — the number of people in the queue (1 ≤ n ≤ 3000). Then n lines contain descriptions of the people as "namei ai" (one description on one line), where namei is a non-empty string consisting of lowercase Latin letters whose length does not exceed 10 characters (the i-th person's name), ai is an integer (0 ≤ ai ≤ n - 1), that represents the number of people who are higher and stand in the queue in front of person i. It is guaranteed that all names are different.

Output

If there's no acceptable order of the people in the queue, print the single line containing "-1" without the quotes. Otherwise, print in nlines the people as "namei hi", where hi is the integer from 1 to 109 (inclusive), the possible height of a man whose name is namei. Print the people in the order in which they stand in the queue, starting from the head of the queue and moving to its tail. Numbers hi are not necessarily unique.

题解:

以下做法是根据官方题解做的,解释如下。首先按ai排序,ai就是每个人前面比他高的人的人数。越小的排在越前面。接下来直接赋予身高。即n, n-1,.....3, 2,1。什么意思呢?比如根据ai排序后的顺序为b, a, c, d然后b, a, c, d的身高分别为4, 3, 2, 1。接下来你再构造一个vector数组,然后都只考虑当前,因为这样子不会被后面的破坏。什么意思呢?也就是说比如b, a, c, d对应的ai分别为0, 0, 1, 1,那么4就插在0位置上,这时候没有数比他大。不管后面怎么插,都不会破坏b的ai的个数。类似的因为后来插入的数都比较小都不会破坏原先的数量,而且已在vector里面的数都比正要插入的大,只要找准位置插进去都可以的,插完后又会维持不变。

AC代码:

 

# include <iostream>
# include <algorithm>
# include <string>
# include <vector>
using namespace std;
struct man{
	int n;
	string name;
};
man s[3010];
bool cmp(man a, man b){
	return a.n<b.n;
}
vector<pair<string, int> > ans;
int main(){
	int n, i, j, k;
	cin>>n;
	for(i=0; i<n; i++){
		cin>>s[i].name;
		cin>>s[i].n;
	}
	sort(s, s+n, cmp);
	for(i=0; i<n; i++){
		if(s[i].n>i){cout<<-1;return 0;}
		ans.insert(ans.begin()+s[i].n, make_pair(s[i].name, n-i));
	}
	for(i=0; i<n; i++){
		cout<<ans[i].first<<' '<<ans[i].second<<endl;
	}
	return 0;
}
 

 

### Codeforces Round 260 Div. 1 题目及题解 #### A. Vasya and Multisets 在这道题目中,Vasya有一个由n个整数组成的序列。目标是通过将这些数分成若干组,使得每组中的所有数都相同,并且尽可能减少分组的数量。 为了实现这一目的,可以利用贪心算法来解决这个问题。具体来说,在遍历输入数据的同时维护当前最大频率计数器,对于每一个新遇到的不同数值增加一个新的集合[^1]。 ```cpp #include <bits/stdc++..h> using namespace std; void solve() { int n; cin >> n; unordered_map<int, int> freq; for (int i = 0; i < n; ++i) { int x; cin >> x; freq[x]++; } int maxFreq = 0; for (auto& p : freq) { maxFreq = max(maxFreq, p.second); } cout << maxFreq << "\n"; } ``` #### B. Pashmak and Graph 此问题涉及图论领域的一个经典最短路径计算案例。给定一张带权无向图以及起点S和终点T,要求求出从S到T经过至少一条边后的最小花费总和。 Dijkstra算法适用于此类场景下的单源最短路径查询任务。初始化距离表dist[]为无穷大(INF),仅设置起始节点的距离为零;随后借助优先队列选取未访问过的最近邻接顶点u更新其相邻结点v至目前为止所知的最佳到达成本min{dist[u]+w(u,v)}直至找到终止条件即抵达目的地t或处理完毕所有可达区域内的候选者为止。 ```cpp typedef pair<long long,int> pli; const long long INF = LLONG_MAX / 3; struct Edge { int to, cost; }; vector<Edge> G[MAX_V]; long long d[MAX_V]; bool dijkstra(int s, int t){ priority_queue<pli,vector<pl>,greater<pl>> que; fill(d,d+MAX_V,INF); d[s]=0; que.push(pli(0,s)); while(!que.empty()){ pli p=que.top();que.pop(); int v=p.second; if(d[v]<p.first) continue; for(auto e:G[v]){ if(d[e.to]>d[v]+e.cost){ d[e.to]=d[v]+e.cost; que.push(pli(d[e.to],e.to)); } } } return d[t]!=INF; } ``` #### C. DZY Loves Colors 这是一道关于颜色染色的问题。给出长度为N的一维网格,初始状态下每个格子都有一个默认的颜色编号。现在有M次操作机会改变某些位置上的色彩值,最终目的是统计整个条带上共有几种不同的色调存在。 采用离散化技术预处理原始输入并记录下各段连续同色区间的端点坐标范围,之后针对每一次修改请求动态调整受影响部分的信息结构体(如线段树),最后依据累积的结果得出答案。 ```cpp // 假设已经实现了上述提到的数据结构 SegmentTree 和 update 函数 SegmentTree st; for(int i=1;i<=m;++i){ int l,r,c; scanf("%d%d%d",&l,&r,&c); update(l,r,c); } printf("%lld\n",st.query()); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值