首页 > 其他分享 >2021 CSP-J

2021 CSP-J

时间:2024-01-15 22:46:35浏览次数:23  
标签:le string lib int 2021 address CSP block

P7909 分糖果(数学)

题意

给定 \(n,l,r\),求一个数 \(x\),当 \(l \le x \le r\) 时,最大的 \(x \bmod n\) 。

数据规模与约定

对于 \(100\%\) 的数据,\(1 \le n \le l \le r \le 10^9\)。

题解

假设 \(l = K_l * n + R_l , r = K_r * n + R_r , x = K_x * n +R_x\)。我们要求 \(R_x\) 尽可能大。

带入到题目给的不等式中,得出 \(K_l * n + R_l \le K_x * n +R_x \le K_r * n + R_r\)。所以 \(x\) 最小值为 \(l = K_l * n + R_l\)。

现在 \(R_x = R_l\)。我们希望 \(R_x\) 尽可能大,而 \(R_x \le n-1\)。所以我们只需要判断 \(l + n - 1 - R_l\) 是否能取到即可。

但有可能 \(r-l\le n - 1 - R_l\)。所以我们要和 \(r\) 取最小值。

#include<bits/stdc++.h>
using namespace std;
/*====================*/
#define endl "\n"
/*====================*/
typedef long long lnt;
/*====================*/
void Solve(void)
{
	int n, l, r; cin >> n >> l >> r;
	cout << min(l + (n - 1) - (l % n), r) % n << endl;
}
/*====================*/
int main()
{
#ifndef ONLINE_JUDGE
	freopen("IN.txt", "r+", stdin);
#endif
	ios::sync_with_stdio(false);
	cin.tie(NULL), cout.tie(NULL);
	int T = 1; //cin >> T;
	while (T--)Solve();
	return 0;
}

P7910 插入排序(排序,模拟)

题意

给定一个长度为 \(n\) 的数组 \(a\),数组下标从 \(1\) 开始,并且数组中的所有元素均为非负整数。需要支持在数组 \(a\) 上的 \(Q\) 次操作,操作共两种,参数分别如下:

\(1~x~v\):这是第一种操作,会将 \(a\) 的第 \(x\) 个元素,也就是 \(a_x\) 的值,修改为 \(v\)。保证 \(1 \le x \le n\),\(1 \le v \le 10^9\)。注意这种操作会改变数组的元素,修改得到的数组会被保留,也会影响后续的操作

\(2~x\):这是第二种操作,假设对 \(a\) 数组进行排序,需要回答原来 \(a\) 的第 \(x\) 个元素,也就是 \(a_x\),在排序后的新数组所处的位置。保证 \(1 \le x \le n\)。注意这种操作不会改变数组的元素,排序后的数组不会被保留,也不会影响后续的操作

数据规模与约定

对于 \(100\%\) 的数据,\(1 \le n \le 8000\),\(1 \le Q \le 2 \times {10}^5\),\(1 \le x \le n\),\(1 \le v,a_i \le 10^9\),保证在所有 \(Q\) 次操作中,至多有 \(5000\) 次操作属于类型一。

题解

这道题的暴力很好想。每次修改操作完后 sort 一遍即可。

考虑优化,我们注意到至多有 \(5000\) 次修改操作。这提示我们修改操作的复杂度可以为 \(O(n)\)。

做法就是题目的名字,插入排序。对于一个已经有序的序列,如果我们修改了其中一项,这一项要么往前调整要么往后调整。而其他元素不需要被调整。所以复杂度为 \(O(n)\)。

#include<bits/stdc++.h>
using namespace std;
/*====================*/
#define endl "\n"
/*====================*/
typedef long long lnt;
/*====================*/
const int N = 8e3 + 10;
/*====================*/
int n, q;
int val[N];
int idx[N];
/*====================*/
struct Unit
{
	int x, v;
	Unit(int _x = 0, int _v = 0)
	{
		x = _x, v = _v;
	}
	friend bool operator<(const Unit& a, const Unit& b)
	{
		return a.v != b.v ? a.v < b.v : a.x < b.x;
	}
};
Unit arr[N];
/*====================*/
void GetAns(void)
{
	for (int i = 1; i <= n; ++i)
	{
		idx[arr[i].x] = i;
	}
}
void Change(int x, int v)
{
	for (int i = 1; i <= n; ++i)
	{
		if (arr[i].x == x)
		{
			arr[i].v = v;
			for (int j = i; j - 1 >= 1; --j)
			{
				if (arr[j] < arr[j - 1])
				{
					swap(arr[j], arr[j - 1]);
				}
				else
				{

				}
			}
			break;
		}
	}
	for (int i = 1; i <= n; ++i)
	{
		if (arr[i].x == x)
		{
			arr[i].v = v;
			for (int j = i; j + 1 <= n; ++j)
			{
				if (arr[j] < arr[j + 1])
				{
					
				}
				else
				{
					swap(arr[j], arr[j + 1]);
				}
			}
			break;
		}
	}
	GetAns();
}
/*====================*/
void Solve(void)
{
	cin >> n >> q;
	for (int i = 1; i <= n; ++i)
	{
		cin >> val[i];
	}

	for (int i = 1; i <= n; ++i)
	{
		arr[i] = Unit(i, val[i]);
	}
	sort(arr + 1, arr + 1 + n); GetAns();

	for (int i = 1; i <= q; ++i)
	{
		int op; cin >> op;
		if (op == 1)
		{
			int x, v; cin >> x >> v; Change(x, v);
		}
		if (op == 2)
		{
			int x; cin >> x; cout << idx[x] << endl;
		}
	}
}
/*====================*/
int main()
{
#ifndef ONLINE_JUDGE
	freopen("IN.txt", "r+", stdin);
#endif
	ios::sync_with_stdio(false);
	cin.tie(NULL), cout.tie(NULL);
	int T = 1; //cin >> T;
	while (T--)Solve();
	return 0;
}

P7911 网络连接(模拟)

题意

计算机分为两大类:服务机(Server)和客户机(Client)。服务机负责建立连接,客户机负责加入连接。

需要进行网络连接的计算机共有 \(n\) 台,编号为 \(1 \sim n\),这些机器将按编号递增的顺序,依次发起一条建立连接或加入连接的操作。

每台机器在尝试建立或加入连接时需要提供一个地址串。服务机提供的地址串表示它尝试建立连接的地址,客户机提供的地址串表示它尝试加入连接的地址。

一个符合规范的地址串应当具有以下特征:

  1. 必须形如 a.b.c.d:e 的格式,其中 \(a, b, c, d, e\) 均为非负整数;
  2. \(0 \le a, b, c, d \le 255\),\(0 \le e \le 65535\);
  3. \(a, b, c, d, e\) 均不能含有多余的前导 \(0\)。

相应地,不符合规范的地址串可能具有以下特征:

  1. 不是形如 a.b.c.d:e 格式的字符串,例如含有多于 \(3\) 个字符 . 或多于 \(1\) 个字符 : 等情况;
  2. 整数 \(a, b, c, d, e\) 中某一个或多个超出上述范围;
  3. 整数 \(a, b, c, d, e\) 中某一个或多个含有多余的前导 \(0\)。

例如,地址串 192.168.0.255:80 是符合规范的,但 192.168.0.999:80192.168.00.1:10192.168.0.1:088192:168:0:1.233 均是不符合规范的。

如果第 \(i\) 台计算机为服务机,则:

  1. 如果其提供符合规范的地址串且成功建立连接,输出字符串 OK
  2. 如果其提供符合规范的地址串,但由于先前有相同地址串的服务机而无法成功建立连接,输出字符串 FAIL
  3. 如果其提供的地址串不是符合规范的地址串,输出字符串 ERR

如果第 \(i\) 台计算机为客户机,则:

  1. 如果其提供符合规范的地址串且成功加入连接,输出一个正整数表示这台客户机连接到的服务机的编号。
  2. 如果其提供符合规范的地址串,但无法成功加入连接时,输出字符串 FAIL
  3. 如果其提供的地址串不是符合规范的地址串,输出字符串 ERR

数据规模与约定

对于 \(100\%\) 的数据, \(1 \le n \le 1000\)。

题解

#include<bits/stdc++.h>
using namespace std;
/*====================*/
#define endl "\n"
/*====================*/
typedef long long lnt;
/*====================*/
int n;
map<string, int>lib;
/*====================*/
int string_to_int(string str)
{
	int num = 0;
	for (int i = str[0] != '-' ? 0 : 1; i < str.size(); ++i)
	{
		num = num * 10 + str[i] - '0';
	}
	return str[0] != '-' ? num : -num;
}
string int_to_string(int num)
{
	string str;
	bool flag = false;
	if (num < 0)
	{
		num *= -1; flag = true;
	}
	do
	{
		str.push_back(num % 10 + '0'); num /= 10;
	} while (num != 0);
	reverse(str.begin(), str.end());
	if (flag)str = '-' + str;
	return str;
}
/*====================*/
bool Check(string address)
{
	do
	{
		string temp;
		for (auto c : address)
		{
			if (c < '0' || '9' < c)
			{
				temp.push_back(c);
			}
		}
		if (temp != "...:")
		{
			return false;
		}
	} while (false);
	
	vector<string>string_number;
	do
	{
		int last = 0;
		address.push_back('.');
		for (int i = 0; i < address.size(); ++i)
		{
			if (address[i] == ':')
			{
				address[i] = '.';
			}
		}
		for (int i = 0; i < address.size(); ++i)
		{
			if (address[i] == '.' && i > last)
			{
				string_number.push_back(address.substr(last, i - last)); last = i + 1;
			}
		}
	} while (false);

	do
	{
		if (string_number.size() != 5)
		{
			return false;
		}
	} while (false);

	vector<int>int_number;
	do
	{
		for (auto unit : string_number)
		{
			int_number.push_back(string_to_int(unit));
		}
	} while (false);

	do
	{
		for (int i = 0; i < int_number.size(); ++i)
		{
			if (int_to_string(int_number[i]) != string_number[i])
			{
				return false;
			}
		}
	} while (false);

	do
	{
		for (int i = 0; i < int_number.size(); ++i)
		{
			if (i <= 3)
			{
				if (int_number[i] < 0 || int_number[i]>255)
				{
					return false;
				}
			}
			else
			{
				if (int_number[i] < 0 || int_number[i]>65535)
				{
					return false;
				}
			}
		}
	} while (false);

	return true;
}
/*====================*/
void Solve(void)
{
	cin >> n;
	for (int i = 1; i <= n; ++i)
	{
		string kind; cin >> kind; 
		string address; cin >> address;
		if (Check(address))
		{
			if (kind == "Server")
			{
				if (lib[address] == 0)
				{
					cout << "OK" << endl;
					lib[address] = i;
				}
				else
				{
					cout << "FAIL" << endl;
				}
			}
			if (kind == "Client")
			{
				if (lib[address] == 0)
				{
					cout << "FAIL" << endl; 
				}
				else
				{
					cout << lib[address] << endl;
				}
			}
		}
		else
		{
			cout << "ERR" << endl;
		}
	}
}
/*====================*/
int main()
{
#ifndef ONLINE_JUDGE
	freopen("IN.txt", "r+", stdin);
#endif
	ios::sync_with_stdio(false);
	cin.tie(NULL), cout.tie(NULL);
	int T = 1; //cin >> T;
	while (T--)Solve();
	return 0;
}

P7912 小熊的果篮(数据结构,STL,模拟,暴力,珂朵莉树,启发式合并,根号均摊,链表,平衡树,线段树,分块)

题意

给定一个长度为 \(n\) 的 \(01\) 串。连续的 \(0\) 或连续的 \(1\) 为一个块。每次输出所有块的第一个元素的下标,然后将其删除。如果一个块内一个元素都没有,则删除块。如果两个相邻块都为 \(0\) 或都为 \(1\) 则合并为一个块。直到所有元素都被删除为止。

数据规模与约定

对于 \(100\%\) 的数据,\(1 \le n \le 2*10^5\)。

题解

这题怎么实现都可以,有 100 种实现方法。这里我选用 STL 和启发式合并来做。但根据实测,不用启发式合并也能过,并且表现上没有任何差距。

我们用一个 deque 来维护一个块内的下标。用一个 vector 来维护块的下标。

所以输出答案,我们要遍历一遍 vector。并且把 每个 deque 的 front 给 pop 掉。

如果把某个 deque 删空了,考虑合并左右。我们每次让 size 小的合并到 size 大的中,进行启发式合并。

分析复杂度,每个元素都会被输出 1 次,每个元素最多合并 log 次,每次输出答案都要遍历一下块的数量,一个块最多被遍历块内元素个数次。\(O(n+nlogn+n)=O(nlogn)\)。实际上远远达不到这个上界,因为一直在删除,很难合并 log 次,更紧的上界我不会证,但反正远小于 \(O(nlogn)\),我猜测可能接近于 \(O(nloglogn)\)。但即便是 \(O(n \sqrt n )\) 也可以轻松通过此题。

#include<bits/stdc++.h>
using namespace std;
/*====================*/
#define endl "\n"
/*====================*/
typedef long long lnt;
/*====================*/
const int N = 2e5 + 10;
/*====================*/
int n;
int arr[N];
/*====================*/
deque<int>lib[N];
vector<int>block;
/*====================*/
void Solve(void)
{
	cin >> n;
	for (int i = 1; i <= n; ++i)
	{
		cin >> arr[i];
	}

	for (int i = 1; i <= n; ++i)
	{
		if (i == 1 || arr[i] != arr[i - 1])
		{
			block.push_back(block.size());
		}
		lib[block.back()].push_back(i);
	}

	while (!block.empty())
	{
		for (auto idx : block)
		{
			cout << lib[idx].front() << " ";
		}
		cout << endl;
		/*====================*/
		vector<int>_block;
		for (auto idx : block)
		{
			lib[idx].pop_front();
			if (!lib[idx].empty())
			{
				_block.push_back(idx);
			}
		}
		block = _block;
		/*====================*/
		for (int i = 1; i < block.size(); ++i)
		{
			int idx1 = block[i - 1], idx2 = block[i + 0];
			if (arr[lib[idx1].back()] == arr[lib[idx2].front()])
			{
				if (lib[idx1].size() < lib[idx2].size())
				{
					block[i - 1] = block[i + 0] = idx2;
					while (!lib[idx1].empty())
					{
						lib[idx2].push_front(lib[idx1].back());
						lib[idx1].pop_back();
					}
				}
				else
				{
					block[i - 1] = block[i + 0] = idx1;
					while (!lib[idx2].empty())
					{
						lib[idx1].push_back(lib[idx2].front());
						lib[idx2].pop_front();
					}
				}
				block[i - 1] = -1;
			}
		}
		/*====================*/
		_block.clear();
		for (auto idx : block)
		{
			if (idx != -1)
			{
				_block.push_back(idx);
			}
		}
		block = _block;
	}
}
/*====================*/
int main()
{
#ifndef ONLINE_JUDGE
	freopen("IN.txt", "r+", stdin);
#endif
	ios::sync_with_stdio(false);
	cin.tie(NULL), cout.tie(NULL);
	int T = 1; //cin >> T;
	while (T--)Solve();
	return 0;
}

标签:le,string,lib,int,2021,address,CSP,block
From: https://www.cnblogs.com/ProtectEMmm/p/17966568

相关文章

  • 2019 CSP-J
    P5660数字游戏(语法)题意给定一个长度最大为\(8\)的01字符串,求字符串中有多少个\(1\)。题解#include<bits/stdc++.h>usingnamespacestd;/*====================*/#defineendl"\n"/*====================*/typedeflonglonglnt;/*====================*/voidSo......
  • 2023 CSP-J
    P9748小苹果(模拟)题意\(n\)个苹果从左到右排成一列,编号为从\(1\)到\(n\)。每天从左侧第\(1\)个苹果开始,每隔\(2\)个苹果拿走\(1\)个苹果。求出多少天能拿完所有的苹果,编号为\(n\)的苹果是在第几天被拿走。数据规模与约定对于\(100\%\)的数据,\(1\len\le10^9......
  • 2022 CSP-J
    P8813乘方(数学,模拟)题意给定两个数\(a,b\),如果\(a^b\le10^9\),输出\(a^b\)的值。否则输出\(-1\)。数据规模与约定对于\(100\%\)的数据,\(1\lea,b\le10^9\)。题解记得开longlong。如果\(a=1\),那么无论\(b\)是多少结果都是\(1\)。如果\(a\ne1\),那么\(a......
  • 2021-2022 ACM-ICPC Latin American Regional Programming Contest
    Preface唉最近天天前期犯病,读错题占用大量机时还红温,纯在靠队友兜底H板题但刚开始因为没打印自己的KM板子就写个了MCMF上去,然后直接TLE飞,后面找了个别人的板子抄上去才过,I题一个傻逼题题意读错爆WA两发最后1h把L题扔给队友然后跑去看ECF滚榜直播了,只能说从此清北电的格局打开了......
  • 【月伴流星】Win10 LTSC 2021 完整版+商店版+适量精简版多合一安装版2024.01
    采用微软官方2021.11发布的Windows10企业版LTSC2021初始版制作,集成KB5033372KB5011050等2023年12月最新补丁,系统版本号升级至19044.3803恢复NETFramework3.5系统支持,恢复IE11系统支持启用SMB1.0共享,打印等系统支持集成VC2005-2022_x86/x64、DirectX_9.0c_x86/x64等系......
  • 2021-2022 ICPC Northwestern European Regional Programming Contest (NWERC 2021)
    Preface和昨天刚好相反,前期极度崩盘2h2题而且一堆银铜牌题不会但好在后面稳扎稳打慢慢追回来了一点,最后超高罚时8题收场这场一边打一边看ECF的实况,最后看到同校的Wifi暴打全场,实在是ORZA.AccessDenied签到,首先暴力问出长度然后从前往后一位一位确定即可注意实现的时候不......
  • 2024年度CSPM考试时间公布!内附详细报名流程
    CSPM——项目管理专业人员能力评价,是中国人自己的一套项目管理专业人士的评价指南,符合中国国情且符合中国未来发展的一套项目刊专业人员能力评价的标准。经研究,2024年度CSPM各等级评价(项目管理专业人员能力评价)全国统一考试时间如下:CSPM-31月、5月、8月、11月,各举办一次,1月考......
  • AT_zone2021 部分
    前言教练出了个集训赛,就是AT_zone2021vp,赛时没切E,赛后也不想做E,所以不写。ZONe_a用substr拆出来,然后检查是不是ZONe。Code#include<bits/stdc++.h>usingnamespacestd;intmain(){ strings; cin>>s; intans=0; for(inti=0;i<s.size()-4;i++)if(s.substr(......
  • Windows 10 on ARM, version 21H2 (released Nov 2021) ARM64 简体中文版、英文版(企业
    作者主页:sysin.orgWindows10,version21H2(releasedNov2021)ARM64ChineseSimplifiedWindows10,version21H2(releasedNov2021)ARM64English基于ARM的Windows10起初,Windows10(与Windows10移动版不同)只能在采用x86和x64处理器的电脑上运行。现在,Windows10......
  • Office 2021 简体中文 正式版 零售版 32位和64位 官方镜像下载合集
    Office2021零售版1、OfficeProfessionalPlus2021,专业增强版:ProPlus2021Retail.img(Previouslyonlyavailableinvlversion,detailsareunknown)2、OfficeProfessional2021,专业版:Professional2021Retail.img(PlusAccessandPublisher(forPConly))3、OfficeHome&B......