首页 > 其他分享 >2022 CCPC 威海站

2022 CCPC 威海站

时间:2024-10-13 21:18:10浏览次数:13  
标签:std 威海 state int CCPC cin add 2022 define

写在前面

时间复杂度与数据范围的关系

计算机 1 秒大约能执行 5e8 次计算,假设时间限制为 1 秒,时间复杂度和数据范围对应如下:

O(n) 的算法能解决的数据范围在 n <= 1e8
O(nlogn) 的算法能解决的数据范围在 n <= 1e6
O(n^2) 的算法能解决的数据范围在 n <= 5e3
O(n^3) 的算法能解决的数据范围在 n <= 3e2
O(2^n) 的算法能解决的数据范围在 n <= 25
O(n!) 的算法能解决的数据范围在 n <= 11

题解

Problem A 毒奶

题意

TI 比赛有 n 只冠军队伍,每个队伍由五个选手组成,每个 选手分别打 1-5 号位中的一个,一个选手永远只打一个位置,不会打其他位置。有 m 名选手组队,问最多能组多少队,满足每个队内至少有一名冠军选手。

代码

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;

unordered_map<string, int> name;
int pos[10], cham[10];

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	int n;
	cin >> n;
	for(int i = 1; i <= n; i++)
	{
		for(int j = 1; j <= 5; j++)
		{
			string s;
			cin >> s;
			name[s] = 1;
		}
	}
	
	int m;
	cin >> m;
	for(int i = 1; i <= m; i++)
	{
		string s;
		int x;
		cin >> s >> x;
		pos[x]++;
		if(name.count(s) != 0)
		{
			cham[x]++; 
		}
	}
	
	int pos_min_num = INT_MAX, cham_num = 0;
	for(int i = 1; i <= 5; i++)
	{
		pos_min_num = min(pos_min_num, pos[i]);
		cham_num += cham[i];
	}
	cout << min(pos_min_num, cham_num);
	return 0;
}

Problem C 草

题意

给定平面上 n 个点,要求选出其中 5 个不同的点,并选定 1 个中心点 A 向其他 4 个点 B, C, D, E 连出 4 条线段,要求这四条线段任意两条的交点都仅有中心点 A。

代码

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;

const int N = 25005;
int x[N], y[N];
int n;

bool check()
{
	if(n < 5)
	{
		return false;
	}
	set<pair<int, int>> s;
	for(int i = 2; i <= n; i++)
	{
		int dx = x[i] - x[1];
		int dy = y[i] - y[1];
		int t = abs(__gcd(dx, dy));
		if(dx < 0)
		{
			dx = -dx;
			dy = -dy;
		}
		s.insert({dx / t, dy / t});
	}
	if(s.size() == 1)
	{
		return false;
	}
	return true;
}

bool valid_point(int o)
{
	set<pair<int, int>> s;
	for(int i = 1; i <= 4; i++)
	{
		int dx = x[i] - x[o];
		int dy = y[i] - y[o];
		int t = abs(__gcd(dx, dy));
		if(dx < 0)
		{
			dx = -dx;
			dy = -dy;
		}
		s.insert({dx / t, dy / t});
	}
	if(s.size() == 1)
	{
		return false;
	}
	return true;
}

bool valid_permulation(int o)
{
	set<pair<int, int>> s;
	for(int i = 1; i <= 4; i++)
	{
		int dx = x[i] - x[o];
		int dy = y[i] - y[o];
		int t = abs(__gcd(dx, dy));
		if(dx < 0)
		{
			dx = -dx;
			dy = -dy;
		}
		s.insert({dx / t, dy / t});
	}
	if(s.size() == 1)
	{
		return false;
	}
	return true;
}

bool valid_permulation(vector<int>& v)
{
	set<pair<int, int>> s;
	for(int i = 1; i < 5; i++)
	{
		int dx = x[v[i]] - x[v[0]];
		int dy = y[v[i]] - y[v[0]];
		int t = abs(__gcd(dx, dy));
		s.insert({dx / t, dy / t});
	}
	if(s.size() != 4)
	{
		return false;
	}
	return true;
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	int T;
	cin >> T;
	while(T--)
	{
		cin >> n;
		for(int i = 1; i <= n; i++)
		{
			cin >> x[i] >> y[i];
		}
		if(check() == false)
		{
			cout << "NO" << endl;
			continue;
		}
		
		vector<int> v = {1, 2, 3, 4};
		for(int i = 5; i <= n; i++)
		{
			if(valid_point(i))
			{
				v.emplace_back(i);
				break;
			}
		}
		
		while(next_permutation(v.begin(), v.end()))
		{
			if(valid_permulation(v))
			{
				cout << "YES" << endl;
				for(auto i : v)
				{
					cout << x[i] << " " << y[i] << endl;
				}
				break;
			}
		}
	}
	return 0;
}

Problem D 中国跳棋

题意

给定六边形棋盘每个格子的分数,询问若干初始的棋子摆放方式,问按照规则移除棋子最多得多少分。
移除棋子有两种方式,一种是直接移除一个棋子,不得分; 另一种是用一个棋子跳过其相邻棋子,移除被跳过的棋子并且得分增加被移除棋子所在的格子的分数。

代码

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;

const int N = 19;
int w[N];
int dp[1 << N], vis[1 << N];
vector<pair<int, int>> v[N];

void add(int mid, int a, int b)
{
	v[mid].push_back({a, b});
	v[mid].push_back({b, a});
}

void init()
{
	memset(dp, -0x3f, sizeof dp);
    dp[0] = 0, vis[0] = 1;
	add(1, 0, 2);
	add(3, 0, 7);
    add(4, 0, 9), add(4, 1, 8), add(4, 3, 5);
    add(5, 1, 10), add(5, 2, 9), add(5, 4, 6);
    add(6, 2, 11);
    add(8, 3, 13), add(8, 4, 12), add(8, 7, 9);
    add(9, 4, 14), add(9, 5, 13), add(9, 8, 10);
    add(10, 5, 15), add(10, 6, 14), add(10, 9, 11);
    add(12, 7, 16);
    add(13, 8, 17), add(13, 9, 16), add(13, 12, 14);
    add(14, 9, 18), add(14, 10, 17), add(14, 13, 15);
    add(15, 11, 18);
    add(17, 16, 18);
}

int dfs(int state)
{
	if(vis[state])
	{
		return dp[state];
	}
	
	for(int i = 0; i < N; i++)
	{
		if(((state >> i) & 1) == 0)
		{
			continue;
		}
		dp[state] = max(dp[state], dfs(state - (1 << i)));
	}
	
	for(int i = 0; i < N; i++)
	{
		if(((state >> i) & 1) == 0)
		{
			continue;
		}
		for(auto p : v[i])
		{
			int a = p.first, b = p.second;
			if((((state >> a) & 1) == 0) || (((state >> b) & 1) == 1))
			{
				continue;
			}
			dp[state] = max(dp[state], dfs(state - (1 << i) - (1 << a) + (1 << b)) + w[i]);
		}
	}
	
	vis[state] = 1;
    return dp[state];
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	for(int i = 0; i < 19; i++)
	{
		cin >> w[i];
	}
	init();
	int n;
	cin >> n;
	while(n--)
	{
		string s, t;
		for(int i = 0; i < 5; i++)
		{
			cin >> t;
			s += t;
		}
		int state = 0;
		for(int i = 0; i < N; i++)
		{
			if(s[i] == '#')
			{
				state += (1 << i);
			}
		}
		cout << dfs(state) << endl;
	}
	return 0;
}

Problem E Python将比c++更快

题意

给出 n 个 Python 版本的运行时间,依据最后两个版本的运行时间画出一次函数之后判断是否会在未来某个版本运行时 间超过 C++。

代码

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;

const int N = 1e6 + 5;
int a[N];

signed main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	int n, k;
	cin >> n >> k;
	for(int i = 1; i <= n; i++)
	{
		cin >> a[i];
	}
	
	for(int i = n + 1; i <= 1e6; i++)
	{
		a[i] = max(0ll, 2ll * a[i - 1] - a[i - 2]);
		if(a[i] < k)
		{
			cout << "Python 3." << i << " " << "will be faster than C++" << endl;
			exit(0);
		}
	}
	cout << "Python will never be faster than C++" << endl;
	return 0;
}

Problem G 二年级

题意

\sum_{k=l}^{r}[\operatorname{gcd}(k \oplus X, X)=1] 多组询问。其中 ⊕ 为异或运算。

代码

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;

const int N = 2e6 + 5;
int pre[N];

signed main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	int x, n;
	cin >> x >> n;
	int c = 1;
	while(c < x)
	{
		c *= 2;
	}
	for(int i = 1; i <= c; i++)
	{
		pre[i] = pre[i - 1] + (__gcd(i * x ^ x, x) == 1);
	}
	while(n--)
	{
		int l, r;
		cin >> l >> r;
		l--;
		int res = 0;
		res -= (l / c) * pre[c];
		res -= pre[l % c];
        res += (r / c) * pre[c];
        res += pre[r % c];
        cout << res << endl;
	}
	return 0;
}

Problem I 龙的血统

题意

合成一个龙蛋需要 n 种精华,其中第 i 种精华需要 ai 个单位。
有 k 种工具龙,第 j 种工具龙总共有 bj 条,且每单位时间 能产出 2^(j − 1) 单位的任意一种精华。
你需要将每条工具龙分配去生产某种精华,并最大化每单位 时间内能产生的龙蛋数量。

代码

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;

const int N = 5e4 + 5;
int a[N], b[25], bb[25];
int n, k;

int check(int x)
{
	if(x == 0)
	{
		return 1;
	}
	for(int i = 1; i <= k; i++)
	{
		bb[i] = b[i];
	}
	priority_queue<int> q;
	for(int i = 1; i <= n; i++)
	{
		q.push(a[i] * x);
	}
	int maxlevel = k;
	while(!q.empty())
	{
		if(maxlevel == 0)
		{
			return 0;
		}
		int topq = q.top();
		int numl = (1ll << (maxlevel - 1));
		q.pop();
		if(topq <= numl)
		{
			bb[maxlevel]--;
			if(bb[maxlevel] == 0)
			{
				maxlevel--;
			}
		}
		else
		{
			int cnt = min(topq / numl, bb[maxlevel]);
			bb[maxlevel] -= cnt;
			topq -= cnt * numl;
			if(bb[maxlevel] == 0)
			{
				maxlevel--;
			}
			if(topq > 0)
			{
				q.push(topq);
			}
		}
	}
	return 1;
}

signed main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	int T;
	cin >> T;
	while(T--)
	{
		cin >> n >> k;
		int suma = 0, totb = 0;
		for(int i = 1; i <= n; i++)
		{
			cin >> a[i];
			suma += a[i];
		}
		for(int i = 1; i <= k; i++)
		{
			cin >> b[i];
			totb += (1ll << (i - 1)) * b[i];
		}
		
		int left = 0, right = totb / suma + 1;
		while(left < right)
		{
			int mid = left + ((right - left) >> 1);
			if(check(mid))
			{
				left = mid + 1;
			}
			else
			{
				right = mid;
			}
		}
		cout << left - 1 << endl;
	}
	return 0;
}

Problem J 吃饭,睡觉,重复

题意

给定 n 个数 a1, a2..., an,以及 k 条限制,每条形如 limit[xi] = yi。两个人进行游戏,每次选一个大于 0 的数并减去 1,如果出现某个数 t 的出现次数 cnt[t] 大于上限 limit[t] 或者无法操作就输了,问谁赢。

代码

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;

const int N = 1e5 + 5;
int a[N];

signed main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	int T;
	cin >> T;
	while(T--)
	{
		int n, k;
		cin >> n >> k;
		for(int i = 1; i <= n; i++)
		{
			cin >> a[i];
		}
		sort(a + 1, a + 1 + n);
		
		map<int, int> mp;
		set<int> s;
		while(k--)
		{
			int x, y;
			cin >> x >> y;
			mp[x] = y;
			if(y == 0)
			{
				s.insert(x);
			}
		}
		s.insert(-1);
		s.insert(1e18);
		
		int ans = 0;
		for(int i = 1; i <= n; i++)
		{
			int x = a[i];
			auto p = lower_bound(s.begin(), s.end(), x);
			p = prev(p);
			ans += x - *p - 1;
			if(mp.count(*p + 1))
			{
				mp[*p + 1]--;
				if(mp[*p + 1] == 0)
				{
					s.insert(*p + 1);
				}
			}
		}
		
		cout << ((ans % 2 == 1) ? "Pico" : "FuuFuu") << endl;
	}
	return 0;
}

标签:std,威海,state,int,CCPC,cin,add,2022,define
From: https://blog.csdn.net/hehe_666888/article/details/142887219

相关文章

  • 洛谷P8818 [CSP-S 2022] 策略游戏
    Problem给出两个数组A,B,进行q次询问,每次分别给出这两个数组的某个区间l1,r1,l2,r2,也就是\(A_{l1\simr1}\)与\(B_{l2\simr2}\),有两位同学小L和小Q分别从A,B的以上区间中选一个数,而两数乘积为此次操作的分数,小L希望分数大,小Q希望分数小,请问他们每次以最优策略进行游戏,分数将会......
  • 信息学奥赛复赛复习16-CSP-J2022-01乘方-循环特判、pow函数、快速幂
    PDF文档公众号回复关键字:20241012此前解析题,P8813[CSP-J2022]乘方,给出了循环的解题思路,当时在洛谷提交是通过的,后台收到留言,a=1,b=1e9会炸吧?,确实啊整除要求1s内循环次数最大可以到10^7,现在测试数据明显大很多,按测试数据有这个可能,没想到CSP普及组第1题竟然翻车,去CCF官网......
  • 2011-2022年各省金融监管水平数据(含原始数据+计算过程+计算代码)
    2011-2022年各省金融监管水平数据(含原始数据+计算过程+计算代码)1、时间:2011-2022年2、来源:国家统计局、统计年鉴3、指标:金融业增加值、金融监管支出、金融监管水平4、计算方法:金融监管水平=金融监管支出/金融业增加值5、指标解释:金融监管水平是指政府及其指定机构通过法......
  • 学年2022-2024-1学号20241311《计算机基础与程序设计》第3周学习总结
    学期(2024-2025-1)学号(20241311)《计算机基础与程序设计》第3周学习总结作业信息这个作业属于哪个课程<班级的链接>(2024-2025-1-计算机基础与程序设计](https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP))这个作业要求在哪里<作业要求的链接>((https://edu.cnblo......
  • The 2022 ICPC Asia Hangzhou Regional Programming Contest K. Master of Both
    题目链接题意:给定n个字符串,然后给定q种字典序规则,在这q种字典序规则下求出这n个字符串的逆序对数量。思路:我们发现q很大,对于每一种排序规则都遍历一遍n个字符串去求逆序对的数量复杂度太高,所以考虑预处理。我们知道要判断两个字符串字典序的大小关系,只需要知道它们第......
  • VS2019/2022配置C++ OpenCV4.10.0环境
    一、下载opencv4.10.0官网链接:https://opencv.org/ 安装的时候记住安装路径,本人安装到E盘 二、新建C++项目1、本人新建C++/CLR.Netframework项目 2、右击打开C++项目属性2.1、添加包含目录 此处本人配置的是绝对地址,拷贝build文件夹到程序目录,然后配置相对地......
  • 20222316 2024-2025-1 《网络与系统攻防技术》实验一实验报告
    一、实验内容缓冲区溢出定义:缓冲区溢出是一种程序错误,在这种情况下,数据被写入到内存中的缓冲区时超过了该缓冲区所能容纳的最大容量。当超过缓冲区的边界时,额外的数据会溢出到相邻的内存位置中,覆盖掉其他数据或指令,导致程序行为异常或系统安全漏洞。缓冲区溢出的原因:编程......
  • 20222311 2024-2025-1 《网络与系统攻防技术》实验一实验报告
    202223112024-2025-1《网络与系统攻防技术》实验一实验报告1.实验内容本次实验主要内容为BOF注入攻击,任务如下:掌握反汇编及其指令修改程序的机器指令,从而实现BOF注入攻击注入一段Shellcode,以实现BOF注入攻击2.实验过程任务1:修改可执行文件机器指令,改变程......
  • # 20222409 2024-2025-1 《网络与系统攻防技术》实验一实验报告
    1.实验内容1.1逆向工程与汇编基础:掌握了汇编指令(如NOP、JMP等)在控制程序流中的作用。学会使用objdump反汇编可执行文件,并通过十六进制编辑器修改机器码以改变程序执行流程。1.2缓冲区溢出(BufferOverflow)原理:了解堆栈结构和返回地址覆盖,理解如何通过超长输入覆盖返回地址来控......
  • 20222318 2024-2025-1 《网络与系统攻防技术》实验一实验报告
    一.实验内容(一)本周学习内容本周学习了缓冲区溢出的相关原理,包括简单的汇编代码、缓冲区溢出本质、堆栈的工作原理、Shellcode的编写等等。(二)实验涉及知识点(1)Linux基本操作:①熟悉Linux环境:能够在Linux系统中进行基本的文件操作、目录导航,如cd等。②常用指令理解:如管道(|)、输入......