首页 > 其他分享 >模拟赛改题记录

模拟赛改题记录

时间:2024-12-17 20:21:35浏览次数:3  
标签:记录 int 复杂度 cin long vm 改题 vn 模拟

12-15模拟赛

其实很简单,其实真的很烂到家了:(

T1 坦克

考虑一次性快进到减少或者减少的时间,需要的回合数,然后算出回合之后的状态 。
重复这个过程,直到某一方的坦克被打完,时间复杂度\(O(n+m)\)
很简单的一道小模拟,记录每回合的损失情况,处理好盈余攻击力即可
代码如下(有些丑)

#include<bits/stdc++.h>
using namespace std;
int T;
int n,m,a,b,vm,vn,jx,jy,bn,bm;
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin>>T;
	for(int i=1;i<=T;i++){
		cin>>n>>m>>a>>b;
		vm=a,vn=b;//盈余攻击力 
		while(n&&m){
			jx=jy=0;//每回合双方会被消灭的坦克数 
			int xn=n,xm=m;//双方攻击力 
			if(xn>=vm){
				xn-=vm,jy++;
				if(xn>=a){
					bm=xn/a;
					jy+=bm;
					if(xn%a) vm=a-(xn%a);
					else vm=a;
				}
				else vm=a-xn; 
			}
			else vm-=xn;
			if(xm>=vn){
				xm-=vn,jx++;
				if(xm>=b){
					bn=xm/b;
					jx+=bn;
					if(xm%b) vn=b-(xm%b);
					else vn=b;
				}
				else vn=b-xm;
			}
			else vn-=xm;
			n-=jx,m-=jy;
			if(n<=0){
				cout<<"0"<<"\n";
				break;
			}
			else if(m<=0){
				cout<<n<<"\n";
				break;
			}
		}
	}
	return 0;
}

但是我的赛时代码成功的零分了(大胜利
补充 \(j0,j1,jn;y0,y1,yn\) 均包含于cmath头文件当然我只记住了y0,y1,yn,警钟撅烂

T2 火柴棍

csp2024-j组T3,只是加了一个取模
代码如下

#include<bits/stdc++.h>
using namespace std;
const long long mod=998244853;
int T,n,num;
long long pw[150000],lz[150000],ans;
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	pw[0]=1;
	for(int i=1;i<=149999;i++) lz[i]=(lz[i-1]*10+1)%mod,pw[i]=pw[i-1]*10%mod;
	cin>>T;
	while(T--){
		cin>>n;
		if(n<7){
			if(n==2) cout<<"1\n";
			if(n==3) cout<<"7\n";
			if(n==4) cout<<"4\n";
			if(n==5) cout<<"2\n";
			if(n==6) cout<<"0\n";
			continue;
		}
		num=n/7,n=n%7,ans=0;
		if(n==1) num--,ans=10;
		if(n==2) ans=1;
		if(n==3){
			if(num>1) num-=2,ans=200;
			else num--, ans=22;
		}
		if(n==4) num--,ans=20;
		if(n==5) ans=2;
		if(n==6) ans=6;
		cout<<(ans*pw[num]%mod+lz[num]%mod*8%mod)%mod<<"\n";
	}
	return 0;
}

分讨模数,预处理8的字符串即可
以后这种大考结束后,切记把题都看一遍,改一遍,说不定哪天就会考到

T3 子集计数

计数DP是比较容易想到的,暴力做法就是每次枚举从 \(1\) 到 \(i-1\) 的$ a_{i}$ ,满足子集关系则加上答案,时间复杂度 \(O(n^2)\),可以拿到20分。( 补充一些二进制下判断子集的方法:\(a \wedge b == a\) , \(a \vee b == b\) 均表示 \(a\) 是 \(b\) 的子集 ps: \(\wedge\) 代表&, \(\vee\) 代表| )代码如下

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,a[100005],dp[100005];
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++){
		dp[i]=1;
		for(int j=1;j<i;j++){
			if(a[j]<=a[i]&&(a[j]|a[i])==a[i])dp[i]+=dp[j];
		}
		cout<<dp[i]<<"\n";
	}
	return 0; 
} 

考虑优化:
观察到数据范围 \(2^{16}\) ,这其实是一个并不大的数,我们有两种方向可以考虑

1、从 \(a_{i}\) 的子集出发:

设 \(g_{s}\)是所有 \(a_{j} = s\) 的 \(f_j\) 之和
转移时枚举 \(s \subseteq a_i , f_i \leftarrow g_s\)( 时间复杂度 \(O(2^m)\) )
转移后 \(g_{a_i} \leftarrow f_i\)
这样的时间复杂度是 \(O(n·2^m)\) ,期望30分

2、从包含 \(a_i\) 的集合出发:

设 \(g_s\) 是所有\(a_j \subseteq s\) 的 \(f_j\) 之和
转移时 \(f_i \leftarrow g_{a_i}\)
转移后枚举 \(s\) 满足 \(a_i \subseteq s , g_s \leftarrow f_i\) ( 时间复杂度 $O(2^m) )
时间复杂度仍为 \(O(n·2^m)\) ,30分

然后呢?

我们发现两个转移方法的复杂度瓶颈都在枚举包含或包含于的集合上,这是直接跟 \(log2(a_i)\) 挂钩的,并且 \(a_i \leq 2_{16}\)
那么对单个 \(a_i\) ,运用状压的思想,将它折半,就可以用两个不大于 \(2_{16}\) 的数表示出来
同样的, \(g\) 数组也可以用这样的思想存储( 不要被固化思维误导,一个 \(2^8\) 的二维数组是完全开的下的 ),在它的二维中,一位存相等,一位存包含于的集合,这样不论在转移还是更新是,都只需要枚举一维,另一位是可以直接表示出来的,时间复杂度就成功的缩减到了 \(O(n·2^{m/2})\) !
形式化的,我们设 \(g_{s,t}\) 表示 \(a_j>>8 \subseteq s\) 且 \(a_j \wedge 256 = t\) 的所有 \(f_j\) 的和 ( \(a_j>>8\) 即取二进制前八位 ,\(a_j \wedge 255\) 即取二进制后八位 )
转移时枚举 \(t \subseteq a \wedge 255\) ,令 \(s=a_i>>8\) ,\(f_i \leftarrow g_{s,t}\)
转移后枚举 \(s\) 满足 \(a_i>>8 \subseteq s\) ,令 \(t=a_i \wedge 255\) ,\(g_{s,t} \leftarrow f_i\)
时间复杂度 \(O(n·2^{m/2})\) ,期望得分 100
代码如下

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define mod 998244353
ll n,a[100005],m;
ll f[100005],g[300][300];
int main(){
//	freopen("count.in","r",stdin);
//	freopen("ans.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		f[i]=1;
	}
	for(int i=1;i<=n;i++){
		int x=a[i]&255;
		for(int t=0;t<=x;t++){
			if((t|x)==x) f[i]=(f[i]+g[a[i]>>8][t])%mod;
		}
		for(int s=0;s<=255;s++){
			if(((a[i]>>8)|s)==s) g[s][a[i]&255]=(g[s][a[i]&255]+f[i])%mod; 
		}
		cout<<f[i]%mod<<"\n";
	}
	return 0;
}

DP还是要多练练,千万不能产生畏难心理

标签:记录,int,复杂度,cin,long,vm,改题,vn,模拟
From: https://www.cnblogs.com/zhangchenhua-awa/p/18608773

相关文章

  • 模拟龟兔赛跑(赛马)
    主要功能:  1)用图形用户界面实现。 2)能设置比赛时间,马匹的数量等。 3)在任意时间段内马匹的速度是随机的。 4)开始比赛之后以动画显示赛马过程。 5)使用多线程技术实现。问题概述模拟龟兔赛跑是一个基于图形用户界面的应用程序,它能够模拟一场龟兔赛跑......
  • Fiddler连接mumu模拟器抓包
    主要介绍mumu模拟器如何设置一、模拟器下载fiddler证书保持本机fiddler运行状态模拟器打开localhost:8888(端口号),点击下载证书二、安装证书信任路径:模拟器-网络和互联网-互联网-网络偏好设置安装证书,选择下载好的fiddler证书即可三、开启手动代理修改网络设置为手动......
  • 记录使用python遇到的问题
    pycharm和python版本问题pycharm官网从官网上查看不同版本的pycharm支持什么版本的python。版本不兼容,后续会出现一些莫名其妙的问题。比如说:我安装的是python3.11.3版本,但是提示的有误,以及一些报错。而且在创建虚拟环境的时候也一直有问题。如何卸载pycharm使用Uni......
  • CMake学习2024.12.9问AI的问题的记录
    vim如何将命令行窗口放入一个子页面中在Vim中将命令行窗口放入一个子页面(分割窗口)中,可以使用内置的终端功能。以下是具体步骤:##前提条件确保你使用的Vim版本支持终端功能。Vim8.0及以上版本和Neovim都支持内置终端。如果你使用的是较旧的Vim版本,建议升级或使用Ne......
  • sqli-labs关卡记录24
    这里演示一个二次注入,通俗来说就是,攻击者构造的恶意数据存储在数据库后,恶意数据被读取并进入到SQL查询语句所导致的注入。防御者可能在用户输入恶意数据时对其中的特殊字符进行了转义处理,但在恶意数据插入到数据库时被处理的数据又被还原并存储在数据库中,当Web程序调用存储在......
  • 深入了解快速排序(qsort)的模拟实现
    这里写目录标题深入了解快速排序(qsort)的模拟实现qsort函数简介排序函数模拟:冒泡排序代替qsort交换函数:灵活处理任意数据类型主函数:结构体排序示例比较函数:定义排序规则深入了解快速排序(qsort)的模拟实现快速排序(qsort)是计算机科学中一个非常著名的排序算法,以其高效和......
  • 打靶记录21——Cereal
    靶机:https://download.vulnhub.com/cereal/Cereal.ova难度:高(最接近真实场景)目标:取得root权限+2Flag攻击方法:主机发现端口扫描信息收集路径枚举密码爆破域名解析匿名FTP子域名爆破源码审计反序列化漏洞进程监视本地提权主机发现sudoarp-scan-l......
  • 如何实现记录用户的操作轨迹并还原?
    记录用户的操作轨迹并还原,通常涉及到前端和后端的配合,但以前端开发为主。以下是一个基本的实现思路:1.确定要记录的操作首先,你需要明确哪些用户操作是需要被记录的。例如,点击按钮、输入文本、滚动页面、鼠标移动等。2.设计数据结构为了记录操作轨迹,你需要设计一个合适的数据......
  • AGC 做题记录
    感觉自己没啥思维,所以做一做AGC。E-BBQHard答案即为:\[\left(\sum_{1\lei\len}\sum_{1\lej\len}\binom{a_i+a_j+b_i+b_j}{a_i+a_j}-\sum_{1\lei\len}\binom{2a_i+2b_i}{2a_i}\right)\times\frac{1}{2}\]现在的问题就是求出前面那一坨:\[\begin......
  • 12月做题记录
    12月做题记录✩trick✯会大部分,要\(tj\)提示✬会小部分/完全没想到,看了\(tj\)才会◈脑电波✡有某一算法的神秘通用性质⊗待补目录12月做题记录CF1725KKingdomofCriticismCF1446D2FrequencyProblem(HardVersion)根号做法✬线性✯✩CF1725KKingdomofCr......