IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 2021暑期杭电多校第一场1,5,8,9题解 -> 正文阅读

[数据结构与算法]2021暑期杭电多校第一场1,5,8,9题解

1.Mod, Or and Everything
简单结论题,打表找规律。
题目大意:现在给你一个数,你要把(n%1) | (n%2) | … | (n%n)计算出来。
思路:首先我们打表找一下规律,发现就是从1到x做或操作,其中当n是奇数时x为(n/2),当n是偶数时x为(n/2 - 1)。观察数据我们会发现n是1e12,一半就是5e11,很明显暴力在1s的时间会爆。所以我们再观察一下。要注意的是这是二进制的运算,我们把目光投到二进制上,发现这样的一个运算得到的是1111这样的数。好的到这里就可以了。
代码:

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define ctx cout << "xxxxx" << endl
#define inf 0x3f3f3f3f
//#define int long long
#define eps 0.000000001
#define forn for(int i = 1; i <= n; i++)
#define ct1 cout << -1 << endl;
const int INF = 0x3f3f3f3f;
const double pai = acos(-1.0);

int main() {
	int t;
	cin >> t;
	while(t--) {
		ll n;
		cin >> n;
		ll tmp = 0;
		if(n & 1) {
			tmp = n/2;
		} else {
			tmp = n/2 - 1;
		}
		vector<ll> tt;
		while(tmp) {
			tt.push_back(tmp%2);
			tmp /= 2;
		}
		ll ans = 1;
		for(int i = 1; i <= tt.size(); i++){
			ans *= 2;
		}
		cout << ans - 1 << endl;
	}

}

5.Minimum spanning tree
结论题
题目大意:
给你一个数n,现在你会有从2到(n-1)的点,让他们两两相连。然后每条边的权值就是两个数的最小公倍数。
思路:
我们先思考到偶数,所有偶数与二相连就是他们本身,然后看到奇数,奇数中有两种数,一种是质数,另一种是非质数。我们看到非质数,他们如果与自己的除数相连,那就是本身。现在就剩下质数,我们把他们与质数相连,就能得到最小的2*质数。现在结论就出来了,从3加到n,然后遇到质数就加上这个质数。
代码:

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define ctx cout << "xxxxx" << endl
#define inf 0x3f3f3f3f
#define int long long
#define eps 0.000000001
#define forn for(int i = 1; i <= n; i++)
#define ct1 cout << -1 << endl;
const int INF = 0x3f3f3f3f;
const double pai = acos(-1.0);
const int maxn = 1e7 + 10;

bool book[maxn];

signed main(){
	for(int i = 2; i <= 1e7; i++){
		if(!book[i]){
			for(int j = 2; i*j <= 1e7 + 10; j++){
				book[i*j] = 1;
			}
		}
	}
	
	int t;
	cin >> t;
	while(t--){
		int n;
		cin >> n;
		int ans = (n+3)*(n-2)/2;
		
		for(int i = 3; i <= n; i++){
			if(!book[i]) ans += i; 
		}
		cout << ans << endl;
	}
	
	
} 

8.Maximal submatrix
单调栈或者悬线法,我不会。
在做本题前请要看一下:单调栈做法基础
题目大意:要在每一列找一个不递减的一段,然后合并,得到面积最大的矩形。
思路:我们每一列分开看,每一列的元素都转换成是否比上一个元素大。这样,每一列复杂的元素就变得简单起来,也可以说,那个元素表示的是当前的高度,不懂的可以自己画图观察,起点不一样是不会影响整个值的。然后对每一行都来一次寻找矩形最大面积的处理。然后取最值。
代码:

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#define ctx cout << "xxxxxx" << endl
using namespace std;
using ll = long long;
int n, m;

const int maxn = 2e3 + 10;

struct vv {
	int val, idx;
};
int b[maxn][maxn];
vv a[maxn][maxn];
void solve() {
	cin >> n >> m;
	for(int i = 1; i <= n+1; i++){
		for(int j = 1; j <= m+1; j++){
			b[i][j] = 0;
			a[i][j].val = 0, a[i][j].idx = 0;
		}
	}
	for(int i = 1; i <= n; i++) {
		for(int j = 1; j <= m; j++) {
			cin >> b[i][j];
		}
	}
	for(int i = n; i >= 1; i--) {
		for(int j = m; j >= 1; j--) {
			if(b[i][j] <= b[i+1][j]) {
				a[i][j].val = a[i+1][j].val + 1;
			} else {
				a[i][j].val = 1;
			}
			a[i][j].idx = j;
		}
	}
	stack<vv> sk;
	sk.push({0,0});
	int ans = 0;
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= m+1; j++){
			while((sk.top()).val > a[i][j].val){
				vv tmp = (sk).top();
				sk.pop();
				ans = max(ans, tmp.val * (j - tmp.idx));		
			}
			sk.push(a[i][j]);
		}
	}
	cout << ans << endl;

}

int main() {
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	int t;
	cin >> t;
	while(t--) {
		solve();
	}
}

9.KD-Graph
据说是签到题,最小生成树。
题目大意:我们现在有n个点和m条边,现在我们要把他们分成k个部分,满足:

  1. 每个部分至少一个点。
  2. 如果顶点p和q(p≠ q)在同一组中,p和q之间必须至少有一条路径满足此路径中的最大值小于或等于D
  3. 如果顶点p和q(p≠ q)在不同的组中,p和q之间不能有任何路径满足此路径中的最大值小于或等于D

思路:把边权从小到大排序,然后并查集合并。有k个部分就可以找到,并且当前合并的就是最小的D。然后你必须把边权相同的都放进去。
官方题解是一开始看作n个部分,然后合并的过程中就可以减少部分的数。然后一个大部分看作一个部分,其余点都是分别做一个部分。这样这满足题意了。当然,据说能用最小生成树做。

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define ctx cout << "xxxxx" << endl
#define inf 0x3f3f3f3f
#define int long long
#define eps 0.000000001
#define forn for(int i = 1; i <= n; i++)
#define ct1 cout << -1 << endl;
const int INF = 0x3f3f3f3f;
const double pai = acos(-1.0);
const int maxn = 1e6 + 10;

int fa[maxn];

inline void iit(int n) {
	for (int i = 0; i <= n; i++) fa[i] = i;
}

int findx(int x) {
	return (x == fa[x] ? x : (fa[x] = findx(fa[x])));
}

void merge(int x, int y) {
	int f_x = findx(x), f_y = findx(y);
	if (f_x != f_y) {
		fa[f_x] = f_y;
	}
}

struct vv {
	int u, v, w;
}p[maxn];

bool cmp(vv a, vv b) {
	return a.w < b.w;
}

void solve() {
	int n, m, k, now, ans;
	cin >> n >> m >> k;
	now = n, ans = 0;
	iit(n);
	for (int i = 1; i <= m; i++) {
		cin >> p[i].u >> p[i].v >> p[i].w;
	}
	sort(p + 1, p + 1 + n, cmp);
	for (int i = 1; i <= m; i++) {
		if (p[i].w != p[i - 1].w) {
			if (now == k)
			{
				cout << ans << endl;
				return;
			}
		}

		int c = findx(p[i].u), d = findx(p[i].v);
		if (c == d) continue;
		now--;
		merge(c, d);
		ans = p[i].w;

	}
	cout << (now == k ? ans : -1) << endl;

}

signed main() {
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	int t;
	cin >> t;
	while (t--) {
		solve();
	}
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-27 16:29:50  更:2021-07-27 16:30:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/7 13:45:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码