并查集和/图书馆/一点点map/

时间:2022-06-22 17:47:30

其实前面写过一次并查集了......乱七八糟的,其实那个方法不太好,也不够简洁= -只是帮助了理解...

其实看这个就很好......https://blog.csdn.net/u013596211/article/details/44599325

一个初始化函数init

一个查找函数,很简单!

  1. int Find(int x)  
  2. {  
  3.     return father[x]==x ? x : father[x]=Find(father[x]);  
  4. }  

或者是

  1. int getfather(int n)  
  2. {  
  3.     while(n!=father[n])  
  4.        n=father[n];  
  5.     return n;  
  6. }  

一个combine函数,也很简单!

  1. void combin(int a, int b)  
  2. {  
  3.     int pa = Find(a), pb = Find(b);  
  4.   
  5.     if(pa != pb)  
  6.         father[pa] = pb;  
  7. }  
并查集还有什么呀?...就没了啊...

查找的时候只要

  1. if(father[i] == i)  
  2.                     ++numb;

就可以了!.....多么简单啊..

【划重点】但是我交的那个题写错了

【while (r != pre[r])

r = pre[r];】

这里!!!!!是pre[r]的值给了r才得以循环下去

是pre[r]的值给了r才得以循环下去

是pre[r]的值给了r才得以循环下去....

https://blog.csdn.net/strongerirene/article/details/79277064这个是帮助理解用的吧...之前写的,其实完全不用这样的....


以及CCCC里面有个图书馆(?)

map
可以有clear()删除所有
还有conut()制定次数
empty(),erase()删除制定  find()查找
4...... 图书馆这个题啊
算法是让你干嘛的
(1)时间可以简化!
int gettime() {
int u, v;
scanf_s("%d:%d", &u, &v);//也没错,真的能省去不少
return u * 60 + v;
}


if (v[0] == 'S') h[u] = w;
if (u == 0) break;
if (v[0] == 'E'&&h.count(u)) {
m++;
sum += w - h[u];
h.erase(u);
}
}


(3)scanf("%d:%d", &u, &v);
真的会简化很多!!也不需要多测试
(4)反正记一下吧!!自己实现的真麻烦啊
有需要关联的,但是需要记录的东西并没那么多
并且只记录一下序号和时间别的拐拐就拐到了!
(5)使用map因为是容器一下子就简化下来了,clear一下一刀切了下去简直完美

还要稍微考虑一下h.earse(u)因为可以借阅很多次
(6)n--这个东西有三组数据,但是读入多少不确定
【这个时候需要写在while(1)里面啊!】
不然n=3只读了三次就没了,要break出来才好!!

还是给个地址...https://pintia.cn/problem-sets/972375971370434560/problems/972376204301107202

然后是标程,...

有关map在这里https://blog.csdn.net/shuzfan/article/details/53115922

可以使用[ ]进行单个插入

啊.....好像有点像前面是索引,后面藏了个大花姑娘(雾)就是后面的时间啦

这写的真好啊....省掉了很多不必要的麻烦,并且很熟练

#include<iostream>

#include<map>
using namespace std;
#define pb push_back
#define mem(a) memset(a,0,sizeof(a))
typedef long long ll;
typedef pair<int, int> pii;

const int mn = 1e3 + 5;

int n;

map<int, int> h;

int gettime() {
	int u, v;
	scanf_s("%d:%d", &u, &v);//也没错,真的能省去不少
	return u * 60 + v;
}//??... 全部都这么表示的话会esay很多...直接相减就可以了!!

int main() {
	scanf_s("%d", &n);
	while (n--) {
		h.clear();//!!!
		int m = 0, sum = 0;
		while (1) {
			int u;
			char v[5];
			scanf_s("%d%s", &u, v);//w是序号,v 是那个状态啊char
			int w = gettime();//直接这么读入???
			if (v[0] == 'S') h[u] = w;
			if (u == 0) break;
			if (v[0] == 'E'&&h.count(u)) {
				m++;
				sum += w - h[u];
				h.erase(u);
			}
		}
		double s = sum * 1.0 / m + 1e-8;
		if (m == 0) s = 0;
		printf("%d %.0f\n", m, s);
	}
	return 0;
}

核心....  读入的时候  时间的设定(记)

h[u]=w/  if (h.count[u])///***这里用点 "."访问

m++;sum+=w-h[u];(其实就是w)

h.earse()   (最开始当然是clear 快了不止几倍啊)


小数点啥的是在干啥待补充......

这怎么都不想更博客了.....orx...

联想到校赛里面那个题栗酱字符串,其实有的完全可以直接用string自己带排序的就解决了.....

多想一想......有的信息其实用不上的,稍微化简一下,保持头脑清醒....