ICPC训练联盟2021暑期训练赛第二场 A / G

本文通过两道算法竞赛题目反思了复杂度计算的重要性。第一题涉及最短路径问题,通过优化排序降低时间复杂度;第二题在二分查找中误判复杂度,实际为线性对数级别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

反思

题目非常长,题意很简单,数据没想到,打都不敢打

A Retribution!

学习了一下标程的代码,实现方式又学了一种新的

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#define ll long long
#define re return
#define Endl "\n"
#define endl "\n"
#define x first
#define y second

using namespace std;

typedef pair<int, int> PII;

int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};

const int N = 1010;

int n, m, p;
PII judger[N];
PII yumao[N];
PII jy[N];
double disy[N];
double disj[N];

double get_dis(PII a, PII b){
	return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

struct node{
	int u, v;
	double w;
};

vector<node> a;

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

bool vis[N][2]; // 0 表示裁判,1表示仓库

int main(){
	cin >> n >> m >> p;
	
	for(int i = 1; i <= n; i++){
		cin >> judger[i].x >> judger[i].y;
	}
	
	for(int i = 1; i <= m; i++){
		cin >> jy[i].x >> jy[i].y;
	}
	
	for(int i = 1; i <= p; i++){
		cin >> yumao[i].x >> yumao[i].y;
	}
	
	double ans = 0;
	
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= m; j++){
			node x;
			x.u = i;
			x.v = j;
			x.w = get_dis(judger[i], jy[j]);
			a.emplace_back(x);
		}
	}
	
	sort(a.begin(), a.end(), cmp);
	
	for(auto i : a){
		int u = i.u;
		int v = i.v;
		double w = i.w;
		if(vis[u][0] || vis[v][1]){
			continue;
		}
		ans += i.w;
		vis[u][0] = vis[v][1] = 1;
	}
	
	memset(vis, 0, sizeof(vis));
	a.clear();
	
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= p; j++){
			node x;
			x.u = i;
			x.v = j;
			x.w = get_dis(judger[i], yumao[j]);
			a.emplace_back(x);
		}
	}
	
	sort(a.begin(), a.end(), cmp);
	
	for(auto i : a){
		int u = i.u;
		int v = i.v;
		double w = i.w;
		if(vis[u][0] || vis[v][1]){
			continue;
		}
		ans += i.w;
		vis[u][0] = vis[v][1] = 1;
	}
	
	printf("%.10lf", ans);
	
	return 0;
}

G Out of Sorts

时间复杂度算错了,我盯着我的二分看了一个小时

以为是 O ( n 2 l o g n ) O(n^2logn) O(n2logn),实际上就是 O ( n l o g n ) O(nlogn) O(nlogn)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#define ll long long

using namespace std;

const int N = 200 + 10;

ll n, m, a, c;
ll x[N];
int backup[N];

int main(){
	cin >> n >> m >> a >> c >> x[0];
	
	for(int i = 1; i <= n; i++){
		x[i] = ((a % m * x[i - 1] % m) % m + c % m) % m;
	}
	
	int ans = 0;
	
	for(int i = 1; i <= n; i++){
		
		ll b = x[i];
		
		int l = 1;
		int r = n;
	
		while(l < r){
			int mid = (l + r) >> 1;
			if(x[mid] == b){
				l = mid;
				break;
			}
			if(x[mid] > b){ // 题目中说的要严格大小于,不能用 r = mid 或者 l = mid 
				r = mid - 1;
			}
			else l = mid + 1;
		}
		if(x[l] == b){
			ans ++;
		}
	}
	
	cout << ans;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值