《AcWing第147场周赛》 牛的语言学(递推) / 孤立点数量(并查集)

牛的语言学

考察知识:递推

题目链接

https://www.acwing.com/problem/content/5559/

题目描述

在这里插入图片描述

思路

在这里插入图片描述

具体代码及注释

#include <iostream>
#include <set>
using namespace std;
const int N = 10010;
bool f[N];
//用递推,f[i]表示f[0...i]可以作为一个词根
int main() {
    string s;
    cin >> s;
    set<string> res;    //用set存储,防止重复,而且排序好了
    int n = s.size();
    f[n - 1] = true;
    //从后往前递推
    for(int i = n - 2; i >= 4; i --) {  //保证最少词根有5个长度
        //枚举后缀长度
        for(int j = 2; j <= 3; j++) {
            //判断后边跟着的第一个后缀是否满足
            if(f[i + j]) {  //从后往前,故f[i + j]已经操作好了,若是可以作为词根,那么操作后缀判断
                //取出后缀和其后相邻的后缀进行判断
                string a = s.substr(i + 1, j);
                string b = s.substr(i + 1 + j, j);  
                //判断是否相等,不相等或者长度不一样则满足条件
                if(a != b || f[i + 5]) {
                    f[i] = true;
                    res.insert(a);  //每次其相邻的第一个后缀进行加入即可
                }
            }
        }
    }
    cout << res.size() << endl;
    for(auto &it : res) cout << it << endl;
    
    
    return 0;
}

孤立点数量

考察知识:并查集

题目链接

https://www.acwing.com/problem/content/5560/

题目描述

在这里插入图片描述

思路分析

在这里插入图片描述

代码及注释

#include <iostream>
using namespace std;
const int N = 100010;
int p[N];
bool st[N]; //判断是否有环
int find(int x) {
    if(p[x] != x)   p[x] = find(p[x]);
    return p[x];
}
int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    //并查集的初始化
    for(int i = 1; i <= n; i++) p[i] = i;
    while(m --) {
        int a, b;
        scanf("%d%d", &a, &b);
        a = find(a), b = find(b);	//找集合的父节点
        if(a == b)  st[b] = true;	//若已经在一个集合中,这时候加边必然会产生环
        else {
            p[a] = b;	//连接a到b的集合中
            st[b] |= st[a];	//若a存在环,则b也必然存在了
        }
    }
        //遍历
        int res = 0;
        for(int i = 1; i <= n; i++)
            if(p[i] == i && !st[i])  //(p[i] == i)遍历所有集合代表节点,若无环,则res = 1,累加
                res++;
    
        cout <<res;
    
    return 0;
}

【搭配购买】

[题目链接]

https://www.acwing.com/problem/content/1254/

[题目描述]

在这里插入图片描述

[AC代码]
#include <iostream>
using namespace std;
const int N = 10010;
int w[N], v[N], p[N];
int f[N];
int n, m, k;
int find(int x) {
	if(p[x] != x)	p[x] = find(p[x]);
	return p[x];
} 

int main() {
	cin >> n >> m >> k;
	for(int i = 1; i <= n; i ++)	p[i] = i;
	for(int i = 1; i <= n; i ++)	cin >> v[i] >> w[i];
	
	while(m --) {
		int a, b;
		cin >> a >> b;
		int pa = find(a), pb = find(b);
		if(pa != pb) {
			w[pb] += w[pa];
			v[pb] += v[pa];
			p[pa] = pb;
		}
	}
	
	for(int i = 1; i <= n; i ++) {
		if(p[i] == i)
		for(int j = k; j >= v[i]; j --)
			f[j] = max(f[j], f[j - v[i]] + w[i]); 
	}
	
	cout << f[k] << endl;
	return 0;
}

【程序自动分析】

题目连接

https://www.acwing.com/problem/content/239/

题目描述

在这里插入图片描述

【AC代码】
#include <iostream>
#include <cstring>
#include <unordered_map>	//用来存储离散化,因为此题不需要保序 
using namespace std;
const int N = 200010;	//每个n最多用两个数,故最大范围为2倍n 
int n, m;
int p[N];
unordered_map<int, int> S;

struct node{
	int x, y, e;	//位置和状态(是否相等) 
}query[N];
//不保序离散化操作
int get(int x) {
	if(S.count(x) == 0)	S[x] = ++ n;	//创建一个下标点
	return S[x]; 
}

int find(int x) {
	if(p[x] != x) p[x] = find(p[x]);
	return p[x];
} 

int main() { 
	int T;
    scanf("%d", &T);
	while(T --) {
		S.clear();
		n = 0;	//对于每个问题,重新进行离散下标编号 
		scanf("%d", &m);
		//存储值并进行离散化 
		for(int i = 0; i < m; i ++) {
			int x, y, e;
			scanf("%d%d%d", &x, &y, &e);
			query[i] = {get(x), get(y), e};
		}
		//初始化每个单集合 
		for(int i = 1; i <= n; i ++) 	p[i] = i;
		//对相等条件进行并查集合并
		for (int i = 0; i < m; i ++ )
            if (query[i].e == 1)
            {
                int pa = find(query[i].x), pb = find(query[i].y);
                p[pa] = pb;
            } 
            
		//对不相等条件进行检索
		bool has_conflict = false;
		for(int i = 0; i < m; i ++) 
			if(query[i].e == 0) {
				if(find(query[i].x) == find(query[i].y)) {
					has_conflict = true;
					break; 
				}
			}
	
		if(has_conflict)	puts("NO");
		else puts("YES");
	}
	return 0;
} 
  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值