《算法竞赛进阶指南》打卡(12/329)

2021-11-20
本文只提供答案

0x00 基本算法

89. a^b

题目链接:a^b
快速幂模板

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int main()
{
	int a, b, p;
	cin >> a >> b >> p;
	int res = 1 % p;
	while (b)
	{
		if (b & 1)res = (LL)a * res % p;
		a = (LL)a * a % p;
		b >>= 1;
	}
	cout << res << endl;
	return 0;
}

90. 64位整数乘法

题目链接:64位整数乘法

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int main()
{
	LL a, b, p, res;
	cin >> a >> b >> p;
	res = 0;
	while (b)
	{
		if (b & 1)res = (a + res) % p;
		a = a * 2 % p;
		b >>= 1;
	}
	cout << res << endl;
	return 0;
}

91. 最短Hamilton距离

题目链接:最短Hamilton距离

#include <bits/stdc++.h>
using namespace std;
const int N = 20;
const int M = 1 << 20;
int n;
int w[N][N];
int f[M][N];
int main()
{
	cin >> n;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			cin >> w[i][j];
	memset(f, 0x3f, sizeof f);
	f[1][0] = 0;
	for (int state = 1; state < 1 << n; state++)
	{
		if (state & 1)
		{
			for (int j = 0; j < n; j++)
			{
				if (state >> j & 1)
				{
					for (int k = 0; k < n; k++)
					{
						f[state][j] = min(f[state][j], f[state - (1 << j)][k] + w[k][j]);
					}
				}
			}
		}
	}
	cout << f[(1 << n) - 1][n - 1] << endl;
	return 0;
}

92. 递归实现指数型枚举

题目链接:递归实现指数型枚举

#include <bits/stdc++.h>
using namespace std;
int n;
vector<int>v;
void dfs(int u)
{
	if (u > n)
	{
		for (auto x : v)
			cout << x << ' ';
		cout << endl;
		return;
	}
	dfs(u + 1);//不选
	v.push_back(u);
	dfs(u + 1);
	v.pop_back();
}
int main()
{
	cin >> n;
	dfs(1);
	return 0;
}

93. 递归实现组合型枚举

题目链接:递归实现组合型枚举

#include <bits/stdc++.h>
using namespace std;
const int N = 30;
int n, m;
bool st[N];
vector<int>v;
void dfs(int u, int start)
{
	if (v.size() >= m)
	{
		for (auto x : v)
			cout << x << ' ';
		cout << endl;
		return;
	}
	for (int i = start; i <= n; i++)
	{
		st[i] = true;
		v.push_back(i);
		dfs(u + 1,i + 1);
		st[i] = false;
		v.pop_back();
	}
}	
int main()
{
	cin >> n >> m;
	dfs(1, 1);
	return 0;
}

94. 递归实现排列型枚举

题目链接:递归实现排列型枚举

#include <bits/stdc++.h>
using namespace std;
const int N = 10;
vector<int>v;
bool st[N];
int n;
void dfs(int u)
{
	if (u > n)
	{
		for (auto x : v)cout << x << ' ';
		cout << endl;
		return;
	}
	for (int i = 1; i <= n; i++)
	{
		if (st[i] == false)
		{

			st[i] = true;
			v.push_back(i);
			dfs(u + 1);
			st[i] = false;
			v.pop_back();
		}
	}
}
int main()
{
	cin >> n;
	dfs(1);
	return 0;
}

95. 费解的开关

题目链接:费解的开关

#include <bits/stdc++.h>
using namespace std;
const int N = 6;
const int INF = 0x3f3f3f3f;
int dx[N] = { -1,0,1,0,0 }, dy[N] = { 0,1,0,-1,0 };
char g[N][N], backup[N][N];
int n;
void turn(int x, int y)
{
	for (int i = 0; i < 5; i++)
	{
		int a = x + dx[i], b = y + dy[i];
		if (a < 0 || a >= 5 || b < 0 || b >= 5)continue;
		g[a][b] ^= 1;
	}
}
int main()
{
	cin >> n;
	while (n--)
	{
		for (int i = 0; i < 5; i++)cin >> g[i];
		int res = INF;
		for (int op = 0; op < 1 << 5; op++)
		{
			memcpy(backup, g, sizeof g);
			int step = 0;
			for (int i = 0; i < 5; i++)
			{
				if (op >> i & 1)
				{
					step++;
					turn(0, i);
				}
			}
			for (int i = 0; i < 4; i++)
			{
				for (int j = 0; j < 5; j++)
				{
					if (g[i][j] == '0')
					{
						step++;
						turn(i + 1, j);
					}

				}
			}
			bool is_dark = false;
			for (int j = 0; j < 5; j++)
			{
				if (g[4][j] == '0')
				{
					is_dark = true;
					break;
				}
			}
			if (!is_dark)res = min(res, step);
			memcpy(g, backup, sizeof backup);
		}
		if (res > 6)res = -1;
		cout << res << endl;
	}
	return 0;
}

96. 奇怪的汉诺塔

题目链接:奇怪的汉诺塔
在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
const int N = 15;
int d[N], f[N];
int main()
{
    memset(d, 0x3f, sizeof d);
	memset(f, 0x3f, sizeof f);
	f[1] = 1;	
	d[1] = 1;
	for (int i = 2; i <= 12; i++)
		d[i] = 2 * d[i - 1] + 1;
	for (int i = 2; i <= 12; i++)
		for (int j = 1; j < i; j++)
			f[i] = min(f[i], 2 * f[j] + d[i - j]);
	for (int i = 1; i <= 12; i++)
		cout << f[i] << endl;
	return 0;
}

99. 激光炸弹

题目链接:激光炸弹

#include <bits/stdc++.h>
using namespace std;
const int N = 5010;
int g[N][N];
int main()
{
	int n, r;
	cin >> n >> r;
	r = min(r, 5001);
	for (int i = 0; i < n; i++)
	{
		int x, y, w;
		cin >> x >> y >> w;
		x++, y++;
		g[x][y] += w;
	}
	for (int i = 1; i <= 5001; i++)
		for (int j = 1; j <= 5001; j++)
			g[i][j] += g[i - 1][j] + g[i][j - 1] - g[i - 1][j - 1];
	int res = 0;
	for (int i = r; i <= 5001; i++)
		for (int j = r; j <= 5001; j++)
			res = max(res, g[i][j] - g[i - r][j] - g[i][j - r] + g[i - r][j - r]);
	cout << res << endl;
	return 0;
}

100. IncDec序列

题目链接:IncDec序列

#include <bits/stdc++.h>
using namespace std;
const int N = 500010;
typedef long long LL;
int n;
int a[N];
int main()
{
	cin >> n;
	for (int i = 1; i <= n; i++)cin >> a[i];
	for (int i = n; i >= 1; i--)a[i] -= a[i - 1];
	LL pos = 0, neg = 0;
	for (int i = 2; i <= n; i++)
	{
		if (a[i] > 0)pos += a[i];
		else neg -= a[i];
	}
	cout << min(pos, neg) + abs(pos - neg) << endl;
	cout << abs(pos - neg) + 1 << endl;
	return 0;
}

101. 最高的牛

题目链接:最高的牛

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int>PII; 
const int N = 10010;
set<pair<int,int>>existed;
int c[N];
int d[N];
int n, p, h, m;
int main()
{
	cin >> n >> p >> h >> m;
	for (int i = 0; i < m; i++)
	{
		int a, b;
		cin >> a >> b;
		if (a > b)swap(a, b);
		if (!existed.count({ a,b }))
		{
			existed.insert({ a,b });
			d[a + 1]--, d[b]++;
		}
	}
	for (int i = 1; i <= n; i++)
	{
		c[i] = c[i - 1] + d[i];
		cout << h + c[i] << endl;
	}
	return 0;
}

102. 最佳牛围栏

题目链接:最佳牛围栏

#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
int cows[N];
double sum[N];
int n, m;
bool check(double avg)
{
	for (int i = 1; i <= n; i++)
		sum[i] = sum[i - 1] + cows[i] - avg;
	double minv = 0;
	for (int i = 0, j = m; j <= n; j++, i++)
	{
		minv = min(minv, sum[i]);
		if (sum[j] - minv >= 0)return true;
	}
	return false;
}
int main()
{
	cin >> n >> m;
	double l = 0, r = 0;
	for (int i = 1; i <= n; i++)
	{
		cin >> cows[i];
		r = max(r,(double) cows[i]);
	}
	while (r - l > 1e-5)
	{
		double mid = (l + r) / 2;
		if (check(mid))l = mid;
		else r = mid;
	}
	cout << (int)(r * 1000) << endl;
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

leimingzeOuO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值