有一天在写洛谷的一道题的时候,我想出来大概思路,但是有几步我想破头也无法实现。
后来看了题解,发现原来结构体可以这样使用。
比如,现在有一个结构体:
struct person {char gender;int age, high, height;
};
它表示的是一个人的一些信息。
然后又给你一个vector容器,里面装的是person类型的元素
vector<person> a;
嗯。。如果我们要将gender,age,high,height都导入进容器里面应该怎么做?
vector<person> a;int main() {a.push_back(person{ 'F', 18, 180, 150});person t = a[0];cout << t.age;
}
只需要按照这个格式:
push_back( 结构体名字{ // 按照成员变量定义的顺序写你想要赋的值// } )
切记,一定要按照顺序结构体里的顺序赋值。
好的,现在我们给出那道题目:
P1878 舞蹈课 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1878
简述一下,我第一次想的思路是将 (异性 and 相邻的差值 )插入最小堆里面
因为,题目要求,如果差值相等,输出最左边的一对,所以我们需要记录每个人站的编号。
然后又因为,如果出列了一对,那么这一对的左右两边的人要自动补齐,所以这样就又多了一对的数据,把这一对数据插入最小堆即可。 这一对的数据很好得到,就是出列的那一对的左边和右边,所以我当时想到了链表。
嗯。。。不过我足足调试了两小时,因为初步的内容很粗糙,细节不够到位。
- 编号为0和编号为n+1的点怎么办?
- 怎么实现如果两数相等让左边的先出列
- 出列的终止条件是什么
最后我想了一个很绝的方法来杜绝0,n+1,直接给0,n+1性别赋值z
然后如果 前面的后面的加起来 == N+B 或者相减== N-B
再加上本地ide背锅(明明最后的答案是对的,但是编辑器不给过,就浪费了好久时间,后面无奈交了,发现对了。。无语)
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cctype>
#include<map>
#include<set>
#include<queue>
#include<numeric>
#include<iomanip>
#include<stack>
#include<list>
using namespace std;#define ll long long
#define lson pos<<1
#define rson (pos<<1)|1
#define father pos>>1
const int N = 2e6 + 7;struct person {char gender;int pos, pre, nxt, val; //一个人的位置,前驱,后继,舞蹈技术,性别
}a[N];struct heap {int margin, left, right;//差值
};bool operator < (heap a, heap b) {if (a.margin != b.margin) {return a.margin > b.margin;}return a.left > b.left;
}priority_queue< heap > dance;bool flag[N];
char gender[N];
int skill[N];
int r[N], l[N];
int main() {int n; cin >> n;for (int i = 1; i <= n; i++)cin >> gender[i];for (int i = 1; i <= n; i++)cin >> skill[i];//gender[n + 1] = 'q';//gender[0] = 'a';for (int i = 1; i <= n; i++) {a[i].pre = i - 1;a[i].nxt = i + 1;a[i].pos = i;a[i].val = skill[i];a[i].gender = gender[i];if (gender[i + 1] + gender[i] == 'B' + 'G' and i < n)dance.push(heap{ abs(skill[i] - skill[i + 1]), i, i + 1 });}int cnt = 0;while (!dance.empty()) {heap t = dance.top();dance.pop();if (flag[t.left] == 0 and flag[t.right] == 0) {cnt++;l[cnt] = t.left;r[cnt] = t.right;flag[t.left] = 1;flag[t.right] = 1;a[a[t.left].pre].nxt = a[t.right].nxt;a[a[t.right].nxt].pre = a[a[t.left].pre].pos;int pre = a[a[t.left].pre].pos;int nxt = a[a[t.right].nxt].pos;if ((int)(a[pre].gender + a[nxt].gender) == int('G' + 'B') and (flag[pre] == 0 and flag[nxt] == 0)) {int margin = abs(a[pre].val - a[nxt].val);dance.push(heap{ abs(margin), pre, nxt });}}}cout << cnt << endl;for (int i = 1; i <= cnt; i++) {cout << l[i] << ' ' << r[i] << endl;}
}//初始化堆:将“异性之间的舞蹈技术差值的绝对值、左边的人是谁、右边的人是谁” 插入堆中.
// 令一个heap变量 t = 堆顶, 那么t的left,right 就是需要出列的人的位置
// 然后用链表把这两个人连接起来
// 然后我们需要判断 t.left 的前面一个人(t.left .pre) .gender
// 和
// t.right 的后面一个人 (t.right.nex).gender
// 是不是异性。
// 如果是异性的话,我们就把这个信息插入到堆里面。
//
//
/*8
BGBGBGBG
1 1 1 8 7 1 7 1
*/