8.23集训笔记
数据结构
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,m,c,a[N],st[N],ans;
void sol1_70(){ // O(n*2) TLE time limit E
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
if(a[i] - a[j] == c) ans ++;
}
}
}
void sol2_70(){ // o(n) RE runtime error
// st[i] 表示 i 的个数
for(int i=1; i<=n; i++) st[ a[i] ] ++;
for(int i=1; i<=n; i++) {
int b = a[i]-c;
ans += st[ b ];
}
}
// map<int,int> mp; mp[x] = y;
void sol3_100(){
map<int,int> mp;
for(int i=1; i<=n; i++) mp[ a[i] ] ++;
for(int i=1; i<=n; i++) {
int b = a[i]-c;
ans += mp[ b ];
}
}
void sol4_100(){
sort(a+1, a+1+n);
for(int i=1; i<=n; i++){
int b = a[i] - c;
int l = lower_bound(a+1, a+1+n, b) - a; // >= b 的第一个元素位置
int r = upper_bound(a+1, a+1+n, b) - a; // > b 的第一个元素位置
// bool f = binary_search(a+1, a+1+n, b); // 返回 b 是否存在
ans += r-l;
}
}
int main(){
cin>>n>>c;
for(int i=1; i<=n; i++) cin>>a[i];
sol4_100();
cout<<ans;
return 0;
}
指针
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=110;
int a = 10;
int* point_a = &a; // 指针
double b = 123.4;
double *pb = &b;
int * pc = NULL; // 空指针
int main(){
cout<<a<<endl; // 10
cout<<&a<<endl; // 0x3f3f3f3f
cout<<point_a<<endl; // 0x3f3f3f3f
cout<<*point_a<<endl; // 0x3f3f3f3f
cout<<b<<endl; // 10
cout<<&b<<endl; // 0x3f3f3f3f
cout<<pb<<endl; // 0x3f3f3f3f
cout<<*pb<<endl; // 0x3f3f3f3f
cout<<pc<<endl;
return 0;
}
单向链表
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
struct Node{
int data;
Node *nxt;
}a[N];
int main(){
a[1] = {11, NULL};
a[2] = {12, NULL};
a[3] = {13, NULL};
// 需求:建立链表:11 -> 13 -> 12 -> NULL; // NULL 表示 0,空,没有
// 结构体元素使用 . 访问
// 指针元素使用 -> 访问
Node *pa = &a[1]; // pa 等效于 &a[1]
a[1].nxt = &a[3];
a[3].nxt = &a[2];
// a[2].nxt = &a[1]; 加上后变为循环链表
while(pa != NULL){
// cout<<(*pa).data<<endl; // (*pa) 等效于 a[1]
cout<<pa->data<<endl;
pa = pa->nxt;
}
return 0;
}
双向链表
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
struct Node{
int data;
Node *pre, *nxt;
}a[N];
int main(){
a[1] = {11, NULL, NULL};
a[2] = {12, NULL, NULL};
a[3] = {13, NULL, NULL};
// 需求:建立链表:11 - 13 - 12 - NULL; // NULL 表示 0,空,没有
// 结构体元素使用 . 访问
// 指针元素使用 -> 访问
Node *pa = &a[1]; // pa 等效于 &a[1]
Node *pb = &a[2]; // pa 等效于 &a[1]
a[1].nxt = &a[3];
a[3].nxt = &a[2];
a[2].pre = &a[3];
a[3].pre = &a[1];
while(pa != NULL){
// cout<<(*pa).data<<endl; // (*pa) 等效于 a[1]
cout<<pa->data<<endl;
pa = pa->nxt;
}
while(pb != NULL){
cout<<pb->data<<endl;
pb = pb->pre;
}
return 0;
}
-
方式1:指针模拟链表
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int q, n=1;
struct Node{
int data;
Node *nxt;
}a[N];
Node* find(int x){ // 返回 x 所在位置,没有就返回 NULL
Node* p = &a[1];
while(p != NULL){
if(p->data == x) break;
p = p->nxt;
}
return p;
}
void insert(int x,int y){ //在 x 后插入
Node *p = find(x);
a[++n] = {y, p->nxt};
p->nxt = &a[n];
}
void erase(int x){ // 删除 x 的后节点
Node *p = find(x);
if(p==NULL || p->nxt==NULL) return;
p->nxt = p->nxt->nxt;
}
int main(){
freopen("data.in", "r", stdin);
cin>>q; a[1] = {1,NULL};
int op,x,y;
while(q--){
cin>>op>>x;
if(op==1){
cin>>y; insert(x, y);
}else if(op==2){
Node *p = find(x);
if(p==NULL || p->nxt==NULL) x=0;
else x = p->nxt->data;
cout<<x<<endl;
}else if(op==3){
erase(x);
}
}
return 0;
}
- 方式2:下标模拟链表
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int q,n=1;
struct Node{
int data;
int nxt;
}a[N];
int find(int x){ // 查询 x 的出现位置,没有就返回 0
int p = 1;
while(p){
if(a[p].data == x) break;
p = a[p].nxt;
}
return p;
}
void insert(int x,int y){
int p = find(x);
a[++n] = {y, a[p].nxt};
a[p].nxt = n;
}
void erase(int x){ // 删除 x的后节点
int p = find(x);
if(p==0) return;
a[p].nxt = a[ a[p].nxt ].nxt;
}
int main(){
// freopen("data.in", "r", stdin);
scanf("%d", &q); a[1] ={1,0};
int op,x,y;
while(q--){
scanf("%d%d",&op,&x);
if(op==1){
scanf("%d", &y); insert(x, y);
}else if(op==2){
int p = find(x);
if(p==0) x = 0;
else x = a[ a[p].nxt ].data;
cout<<x<<endl;
}else if(op==3){
erase(x);
}
}
return 0;
}
- 方式3:数组模拟链表
点击查看代码
栈
队列
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
// 数组模拟队列
int que[N], front=0, tail=-1; // if(front > tail) 为空
int main(){
// 1-7 入队
// for(int i=1; i<=7; i++) que[ ++tail ] = i;
// for(int i=front; i<=tail; i++){
// cout<<que[i]<<" ";
// }
queue<int> q; // STL 的队列
for(int i=1; i<=7; i++) q.push(i);
// while(!q.empty()){
while(q.size()){
cout<<q.front()<<" ";
q.pop();
}
return 0;
}
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=110;
queue<int> q;
int n;
/*
queue<Type> q; //定义队列,Type为数据类型,如int,float,char等
q.push(item); //把item放进队列
q.front(); //返回队首元素,但不会删除
q.pop(); //删除队首元素
q.back(); //返回队尾元素
q.size(); //返回元素个数
q.empty(); //检查队列是否为空
*/
int main(){
freopen("data.in", "r", stdin);
cin>>n; int op,x;
while(n--){
cin>>op;
if(op==1){
cin>>x; q.push(x);
}else if(op==2){
if(q.empty()) cout<<"ERR_CANNOT_POP"<<endl;
else q.pop();
}else if(op==3){
if(q.empty()) cout<<"ERR_CANNOT_QUERY"<<endl;
else cout<<q.front()<<endl;
}else if(op==4){
cout<<q.size()<<endl;
}
}
return 0;
}
优先队列/堆
二叉树
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=110;
struct T{
int lch, rch;
}tree[N];
// tree[i].lch i 的 左儿子
// tree[i].rch i 的 右儿子
void pre(int rt){ // 先序遍历 以 rt为根的子树
if(rt==0) return;
cout<<rt<<" "; // 根
pre(tree[rt].lch);// 左
pre(tree[rt].rch);// 右
}
void in(int rt){ // 中序遍历 以 rt为根的子树
if(rt==0) return;
in(tree[rt].lch);// 左
cout<<rt<<" "; // 根
in(tree[rt].rch);// 右
}
void post(int rt){ // 后序遍历 以 rt为根的子树
if(rt==0) return;
post(tree[rt].lch);// 左
post(tree[rt].rch);// 右
cout<<rt<<" "; // 根
}
int main(){
int n,l,r; cin>>n;
for(int i=1; i<=n; i++) {
cin>>l>>r;
tree[i] = {l,r};
}
pre(1); cout<<endl;
in(1); cout<<endl;
post(1);
return 0;
}
图
图论前置知识:https://blog.csdn.net/smallrain6/article/details/123444632

浙公网安备 33010602011771号