春季测试 2023 我的题解

news2024/11/26 13:36:57

T1 涂色游戏

这道题目还是比较简单的
容易发现,位于 ( x i , y i ) (x_i,y_i) (xi,yi) 的格子的颜色只取决于 ​ x i x_i xi 行与 y i y_i yi 列的颜色。

这时候可以想到开两个数组,分别存储列与行的绘画信息,然后发现前后的互相覆盖可以通过存储绘画顺序来得出。

考虑 L i L_i Li 表示第 i i i 行最后一次被染成什么颜色, U i U_i Ui 表示第 i i i 列最后一次被染成什么颜色,同时记录下这些操作的时间先后顺序。
那么对于最终的格子 ( i , j ) (i,j) (i,j) ,它的颜色就是 L i L_i Li U j U_j Uj 中更晚的一个,简单判断一下然后输出即可。

#include<bits/stdc++.h>
using namespace std;

int read(){
	int x=0,f=1;char ch=getchar();
	while(ch>'9'||ch<'0') {
		if(ch=='-') f=-1;
		ch=getchar(); 
	}
	while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x*f;
}

const int N = 1e5 + 5;
int n, m, q;
pair<int, int> L[N], U[N];

void Init() {
	for (int i = 1; i <= n; ++i) {
		L[i] = make_pair(0, 0);
	}
	
	for (int i = 1; i <= m; ++i) {
		U[i] = make_pair(0, 0);
	}
}
int main() {
	int T=read();
	while (T--){
		n=read(),m=read(),q=read();
		Init();
		for (int i = 1; i <= q; i++) {
			int opt=read(),x=read(),y=read(); 
			if (opt == 0) {
				L[x] = make_pair(y, i);
			} else {
				U[x] = make_pair(y, i);
			}
		}
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				if (L[i].second > U[j].second) {
					cout << L[i].first << ' ';
				} else {
					cout << U[j].first << ' ';
				}
			}
			puts("");
		}
	}
	return 0;
}

T2 幂次

这道题如果在考场上不认真分析也就会做不出来

首先就是骗分:
发现 k = 1 k=1 k=1 ,就直接输出 n n n 就行了

考虑一个比较简单的暴力, 枚举 [ 1 , n ] [1, n] [1,n] 中的每个数作为 a a a , 然后枚举 b b b , 直到 a b ≥ n a^{b} \geq n abn 就让 a + + \mathrm{a}++ a++ 然后重新枚举 b b b , 每个没出现过的数使 a n s + + ans ++ ans++

先不考虑去重, 我们来思考如何优化这个暴力。注意到当我们枚举的 b b b 增加时, 使 a b a^{b} ab 首次 ≥ n \geq n n a a a 会越来越小,由此我们可以对每个 b b b 二分求出一个 a a a 的上界,此时 a a a 的上界是 n n n 次根号级别的。

因为 2 60 ≥ 1 0 18 2^{60} \geq 10^{18} 2601018 , 所以 b b b 实际的范围并不大。对于 k ≥ 3 k \geq 3 k3 的情况我们都可以枚举 b b b 求出 a a a 的上界然后直接暴力求所有快速幂做了。剩下的情况中, k = 1 k=1 k=1 时答案显然为 n n n , 那么 k = 2 k=2 k=2 时如何做?

此时回来考虑去重, 所以求完快速幂后再枚举每个 ≤ b \leq b b x x x 作为新的指数。然后对当前求得的 a b a^{b} ab x x x 次方根, 看是否有正整数解, 就可以判定是否与之前计算过的重复了。

此时 k = 2 k=2 k=2 的情况就迎刃而解了,我们直接令初始 a n s 为 n ans 为 \sqrt{n} ansn 即可。
还要注意 a a a 1 1 1 的情况, 在初始答案上略作修改就行。
时间复杂度比较抽象, 我不会表示, 交了反正能过。

#include<bits/stdc++.h>
using namespace std;
#define int long long
int read() {
	int x=0,f=1;
	char ch=getchar();
	while(ch>'9'||ch<'0') {
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x*f;
}
using namespace std;
using i64 = long long;
i64 n, a[100010];
int k;
long double Qpow(int x, int y) {
	long double res = 1, base = x;
	for (; y; y >>= 1, base *= base) {
		if (y & 1) {
			res *= base;
		}
	}
	return res;
}
int GetRoot(int x, int y) {
	int l = 1, r = x;
	while (l <= r) {
		int mid = (l + r) >> 1;

		if (Qpow(mid, y) > x) r = mid - 1;
		else l = mid + 1;
	}
	return r;
}
signed main() {
	n=read(),k=read();
	i64 res = 1;
	int lim = 0;
	for (int i = k; ; ++i) {
		int v = GetRoot(n, i);
		lim = i;
		if (v <= 1) break;
		a[i] = v - 1;
	}
	for (int i = lim - 1; i >= k; --i) {
		for (int j = i + i; j <= lim; j += i) {
			a[i] -= a[j];
		}
	}
	for (int i = k; i < lim; ++i) {
		res += a[i];
	}
	cout << res << '\n';
	return 0;
}

T3

很显然的一个结论就是连接的路径一定不能相交。证明考虑相交的时候交换两个顶点的顺序一定更优。
假设已经连接的点的集合为 S S S ,那么 S S S 一定在凸多边形上是连续的,因此有一个很显然的 D P DP DP: 设 f ( i , j , 0 / 1 ) f(i, j, 0 / 1) f(i,j,0/1) 表示从 k k k 逆时针转选了 i i i 个,顺时针转选了 j j j 个,当前在左侧 / / / 右侧。转移很明显(用 L ( x ) L(x) L(x) 表示 k k k 逆时针开始的第 x x x 个, R ( x ) R(x) R(x) 表示顺时针的第 x x x 个):

f ( i , j , 0 ) ← f ( i − 1 , j , 0 ) + dis ⁡ ( L ( i − 1 ) , L ( i ) ) f ( i , j , 0 ) ← f ( i − 1 , j , 1 ) + dis ⁡ ( R ( j ) , L ( i ) ) f ( i , j , 1 ) ← f ( i , j − 1 , 0 ) + dis ⁡ ( L ( i ) , R ( j ) ) f ( i , j , 1 ) ← f ( i , j − 1 , 1 ) + dis ⁡ ( R ( j − 1 ) , R ( j ) ) \begin{array}{l} f(i, j, 0) \leftarrow f(i-1, j, 0)+\operatorname{dis}(L(i-1), L(i)) \\ f(i, j, 0) \leftarrow f(i-1, j, 1)+\operatorname{dis}(R(j), L(i)) \\ f(i, j, 1) \leftarrow f(i, j-1,0)+\operatorname{dis}(L(i), R(j)) \\ f(i, j, 1) \leftarrow f(i, j-1,1)+\operatorname{dis}(R(j-1), R(j)) \end{array} f(i,j,0)f(i1,j,0)+dis(L(i1),L(i))f(i,j,0)f(i1,j,1)+dis(R(j),L(i))f(i,j,1)f(i,j1,0)+dis(L(i),R(j))f(i,j,1)f(i,j1,1)+dis(R(j1),R(j))

最终答案就是 min ⁡ 0 ≤ i < n min ⁡ ( f ( i , n − i − 1 , 0 ) , f ( i , n − i − 1 , 1 ) ) \min _{0 \leq i<n} \min (f(i, n-i-1,0), f(i, n-i-1,1)) min0i<nmin(f(i,ni1,0),f(i,ni1,1))
题目要求输出方案,那么就在转移的过程中再记录一个 from ⁡ ( i , j , 0 / 1 ) \operatorname{from}(i, j, 0 / 1) from(i,j,0/1) 表示当前状态是又哪一个转移过来的,最后遍历输出即可。
贴一个证明过程
在这里插入图片描述

#include<bits/stdc++.h>
#define int long long
int read(){
	int x=0,f=1;char ch=getchar();
	while(ch>'9'||ch<'0') {
		if(ch=='-') f=-1;
		ch=getchar(); 
	}
	while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x*f;
}
using namespace std;
const int N=1e3+10;
struct node {
	double x,y;
} a[N];
struct point {
	int l,r,x;
} fa[N][N][2];
int n,m,T;
double f[N][N][2],ans;
bool chmin(double& x,double y) {
	if(x>y) x=y;
	return (x==y);
}
int ex(int x) {
	if(x<=0) x+=n;
	if(x>n) x-=n;
	return x;
}
double dist(int x,int y) {
	return sqrt((a[x].x-a[y].x)*(a[x].x-a[y].x)+(a[x].y-a[y].y)*(a[x].y-a[y].y));
}
signed main() {
	n=read();
	for(int i=1; i<=n; ++i) cin>>a[i].x>>a[i].y;
	double maxn=-1e9;
	for(register int i=1; i<=n; ++i) {
		if(a[i].y>maxn) {
			maxn=a[i].y;
			m=i;
		}
	}
	for(register int i=0; i<=n; ++i) for(register int j=0; j<=n; ++j) f[i][j][0]=f[i][j][1]=1e18;
	f[0][0][0]=f[0][0][1]=0;
	for(register int len=1; len<n; ++len) {
		for(register int l=0; l<=len; ++l) {
			int r=len-l;
			if(l&&chmin(f[l][r][0],f[l-1][r][0]+dist(ex(m+l),ex(m+l-1)))) fa[l][r][0]=(point) {
				l-1,r,0
			};
			if(l&&chmin(f[l][r][0],f[l-1][r][1]+dist(ex(m+l),ex(m-r))))   fa[l][r][0]=(point) {
				l-1,r,1
			};
			if(r&&chmin(f[l][r][1],f[l][r-1][0]+dist(ex(m-r),ex(m+l))))   fa[l][r][1]=(point) {
				l,r-1,0
			};
			if(r&&chmin(f[l][r][1],f[l][r-1][1]+dist(ex(m-r),ex(m-r+1)))) fa[l][r][1]=(point) {
				l,r-1,1
			};
		}
	}
	ans=1e18;
	point jump;
	for(register int i=0; i<n; ++i) {
		if(f[i][n-i-1][0]<ans) {
			ans=f[i][n-i-1][0];
			jump=(point) {
				i,n-i-1,0
			};
		}
		if(f[i][n-i-1][1]<ans) {
			ans=f[i][n-i-1][1];
			jump=(point) {
				i,n-i-1,1
			};
		}
	}
	printf("%lld ",m);
	stack<int> s;
	while(jump.l>0||jump.r>0) {
		s.push((jump.x==0?ex(m+jump.l):ex(m-jump.r)));
		jump=fa[jump.l][jump.r][jump.x];
	}
	while(!s.empty()) printf("%lld ",s.top()),s.pop();
	return 0;
}

T4

这道题骗分要随机化,但是随机化我不会,老师只说了random,所以就先学随机种子
考场随机需谨慎,提防爆零两行泪。
附一个链接 https://blog.csdn.net/yeepom/article/details/8625184
还有一个 :https://blog.csdn.net/xiyangxiaoguo/article/details/104847770
说实在的,考试时打死我我也想不上来用随机数乱搞,就算想到了,也照样不知道怎么用,分析实际情况,我选择写特殊性性质

对于 k = 1 k=1 k=1 的情况 就是求极差
对于 k = 2 k=2 k=2 的情况
考虑将小的数放上面,大的数放下面。
思考一下这样为什么是对的?考虑全局最小值和全局最大值所在的行,显然放在两行不劣于放在同一行,设最小值放上面,最大值放下面,那么要想让上面的数尽量小,下面的数尽量大,就是上面的方法。
下面给出部分分的代码

		if(k==1){
			int minn=1e9,maxn=-1e9;
			for(int i=1;i<=n;i++){
				minn=min(minn,a[1][i]);
				maxn=max(maxn,a[1][i]);
			}
			printf("%d\n",maxn-minn);
		}

k = 1 , 10 p t s k=1,10pts k=1,10pts

FOR(i,0,k-1) FOR(j,1,n){
			b[i][j]=rd;
			if(b[i][j]>mxx) mxx=b[i][j],mxl=j,mxa=i;
			if(b[i][j]<mnn) mnn=b[i][j],mnl=j,mna=i;
		}
		ans=max(mxx-b[mna^1][mnl],b[mxa^1][mxl]-mnn);
		FOR(j,1,n){
			if(j==mxl||j==mnl) continue;
			int tmp1=max(mxx-b[0][j],b[1][j]-mnn);
			int tmp2=max(mxx-b[1][j],b[0][j]-mnn);
			ans=max(ans,min(tmp1,tmp2));
		}
		printf("%d\n",ans);

k = 2 , 20 p t s k=2,20pts k=2,20pts
其实再加上暴力搜索就又能拿 10 p t s 10pts 10pts
CCF如果数据水,就又能操过去几个点

int res;
void dfs(int x){
        if(x>n){
                int tmp=0;
                FOR(i,0,k-1){
                        int mx=0,mn=INF;
                        FOR(j,1,n) mx=max(mx,p[i][j]),mn=min(mn,p[i][j]);
                        tmp=max(tmp,mx-mn);
                }
                res=min(res,tmp);
                return;
        }
        FOR(j,0,k-1){
                FOR(i,0,k-1) p[(j+i)%k][x]=a[i][x];
                dfs(x+1);
        }
}
void solve3(){
        while(T--){
                n=rd;res=INF;
                FOR(i,0,k-1) FOR(j,1,n) a[i][j]=rd;
                dfs(1);printf("%d\n",res);
        }
}

本题拿捏分数: 40 p t s 40pts 40pts

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2228269.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

magic-api简单使用二:自定义返回结果

背景 在上一章 中我们学习了搭建项目和导入文件&#xff0c; 这二天稍微有点时间&#xff0c;研究下这个magic-api的写法。 后续如果需要维护或者更改&#xff0c;也能在项目中尽快上手。 今天我们主要学习自定义返回结果&#xff0c;当然也可以使用官方的。不需要任何更改。…

“启动智能制造引擎 推动新质生产力发展”高峰论坛在京成功举办

在智能制造技术的助力下,北京经开区的智能制造产业稳步发展。2024年10月25日,北京电子科技职业学院图书馆暨北京经济技术开发区公共图书馆举办一场以“启动智能制造引擎 推动新质生产力发展”为主题的高峰论坛于北京亦庄经开区盛元书院圆满落幕。此次论坛为北京经开区智能制造产…

Java 异常处理(6/30)

目录 Java 异常处理 1. 什么是异常 2. 异常处理的关键字 2.1 try-catch 语句 2.2 多个 catch 块 2.3 finally 块 2.4 throw 和 throws 3. 自定义异常 4. 异常处理的最佳实践 总结与后续 Java 异常处理 在软件开发中&#xff0c;异常处理&#xff08;Exception Handl…

ubuntu22.04安装向日葵

1、下载deb安装包 进入官网下载图形版本&#xff1a;https://sunlogin.oray.com/download/linux?typepersonal 2、命令行安装 sudo chmod x 文件名.deb sudo dpkg -i 文件名.deb 3、开始报错的看这里&#xff01; 首先展示一下安装成功的效果图&#xff1a; 接下来是我安…

小米手机投屏到Windows笔记本电脑的3个方法,随便选一个

方法一&#xff1a;Windows系统自带的投屏功能 Windows系统本身的功能很多&#xff0c;其中一项就是接收别的电脑或手机的投屏。 操作步骤一&#xff0c;在Windows电脑里进入【设置】&#xff0c;点击【系统】&#xff0c;往下翻页&#xff0c;找到【投影到此电脑】。 如果这…

漏洞挖掘 | 通过域混淆绕过实现账户接管

由于这是一个私有项目&#xff0c;我将使用 example.com 来代替。 很长一段时间以来&#xff0c;我一直想在漏洞赏金项目中找到一个账户接管&#xff08;ATO&#xff09;漏洞。于是&#xff0c;我开始探索项目范围内的 account.example.com。 我做的第一件事就是注册一个新账…

加密软件有什么功能?

加密软件是一种专门用于保护数据安全的工具&#xff0c;它通过复杂的加密算法来确保数据在传输和存储过程中的机密性和完整性。以下是加密软件通常具备的主要功能&#xff1a; 一、数据加密 文件加密&#xff1a;能够对单个文件或整个文件夹进行加密&#xff0c;确保只有授权…

Python bs4 结合 Scrapy,进行数据爬取和处理

Python bs4 结合 Scrapy&#xff0c;进行数据爬取和处理 在现代数据分析和机器学习领域&#xff0c;数据爬取是获取网页数据的常用方法。Python 提供了许多工具来进行网页爬取&#xff0c;其中 Scrapy 和 BeautifulSoup&#xff08;bs4&#xff09;是最常用的两个库。Scrapy 是…

【p2p、分布式,区块链笔记 Torrent】webtorrent.min.js的实现之appendTo()函数

官方给出的示例通过appendTo函数渲染文件对象&#xff0c;通过torrent.files的元素对象调用&#xff1a; const WebTorrent require(webtorrent)const client new WebTorrent()// Sintel, a free, Creative Commons movie const torrentId magnet:?xturn:btih:08ada5a7a61…

ALIGN_ Tuning Multi-mode Token-level Prompt Alignment across Modalities

文章汇总 当前的问题 目前的工作集中于单模提示发现&#xff0c;即一种模态只有一个提示&#xff0c;这可能不足以代表一个类[17]。这个问题在多模态提示学习中更为严重&#xff0c;因为视觉和文本概念及其对齐都需要推断。此外&#xff0c;仅用全局特征来表示图像和标记是不…

MySQL数据集成至金蝶云星空的解决方案

MySQL数据集成至金蝶云星空的解决方案 SYB生产用料清单新增-深圳天一-半成品-好&#xff1a;MySQL数据集成到金蝶云星空的技术实现 在企业信息化系统中&#xff0c;数据的高效流转和准确对接是确保业务顺畅运行的关键。本文将聚焦于一个具体案例——如何将MySQL中的生产用料清…

javaweb----VS code

前端开发神器&#xff1a;VS Code → 速度快、体积小、插件多 VS Code 安装官网&#xff1a;https://code.visualstudio.com/download VS Code一些必备的插件安装&#xff1a; 1、Chinese (Simplified) 简体中文 2、Code Spell Checker 检查拼写 3、HTML CSS Support 4…

【新闻转载】“假冒 LockBit”来袭:勒索软件借助 AWS S3 偷窃数据,威胁升级

关键要点 Trend团队发现了一些利用 Amazon S3&#xff08;简单存储服务&#xff09;传输加速功能的 Golang 勒索软件样本&#xff0c;用于窃取受害者的文件并上传至攻击者控制的 S3 存储桶。 这些样本中硬编码的 Amazon Web Services (AWS) 凭证被用于追踪与恶意活动关联的 AW…

第十五章 Vue工程化开发及Vue CLI脚手架

目录 一、引言 二、Vue CLI 基本介绍 三、安装Vue CLI 3.1. 安装npm和yarn 3.2. 安装Vue CLI 3.3. 查看 Vue 版本 四、创建启动工程 4.1. 创建项目架子 4.2. 启动工程 五、脚手架目录文件介绍 六、核心文件讲解 6.1. index.html 6.2. main.js 6.3. App.vue 一、…

BEV:针孔相机坐标转换

一 、背景 自动驾驶中经常涉及到不同坐标系之间的坐标转换&#xff0c;在BEV方案中用的比较多的是自车坐标到图像坐标的转换&#xff0c;系统整理了一下坐标转换过程流程。 二 、方法 旋转矩阵计算方法&#xff1a; translation: 平移参数[‘x’, ‘y’, ‘z’] 高阶畸变模型…

开关灯问题(c语言)

样例&#xff1a;10 10 &#xff0c;输出&#xff1a;1&#xff0c;4&#xff0c;9 5 5 &#xff0c;输出&#xff1a;1&#xff0c;4 代码如下 #include<stdio.h> //引入bool值的概念 #include<stdbool.h> int main() {int n 0;//n为灯的数量int m 0;…

centos虚拟机部署opengauss数据库

一、基本信息 1、虚拟机安装的centos版本 2、opengauss版本 地址&#xff1a;https://opengauss.org/zh/download/ 3、opengauss和gaussdb的区别 高斯数据库&#xff08;GaussDB&#xff09;是云数据库&#xff0c;需要购买。 openGaussDB是开源数据库&#xff0c;可以免费…

搜索TV 1.2.4 | 适用于TV端的浏览器应用,设计简洁,功能强大

Klonsdif搜索TV版是一款专为TV端设计的浏览器应用&#xff0c;界面简洁&#xff0c;操作简单&#xff0c;保留最纯粹的浏览体验。支持使用百度、必应、360、搜狗、秘塔AI搜索、360AI搜索、bilibili等内置搜索引擎&#xff0c;也可以直接输入网址访问。全免费、无广告&#xff0…

Spring Boot 实现文件上传下载功能

文章目录 一、原理分析1.1 请求类型1.2 服务器解析 二、功能实现2.1 创建项目并导入依赖2.2 文件上传功能实现2.2.1 文件上传 Service2.2.2 文件上传 Controller 2.3 文件下载功能实现2.3.1 文件下载 Service2.3.2 文件下载 Controller 2.4 文件上传前端代码(可选)2.4.1 上传文…

注册信息合理性验证

表单是网页中的一个重要功能,主要用于用户信息的收集。使用JavaScript进行表单验证对于提升用户体验、减轻服务器负担、确保数据准确性、增强安全性和提高开发效率等方面都具有重要意义。本文详细敍述进行合理化验化必要性和具体实现方法。 一 表单项合理性必要性 主要体现在…