首页 > 其他分享 >10.19至10.22考试总结

10.19至10.22考试总结

时间:2024-10-23 11:11:57浏览次数:1  
标签:10 10.22 int top cin 10.19 考试 freopen dp

10.19noip模拟赛一

T1 序列

算法:dp
观察到所有数 \(\mod 3\),所以只有三种取值\(\{0,1,2\}\),所以想要将原序列模 \(3\) 以后做。经过简单的运算发现,所有数模 \(3\) 以后做是等价的,所以可以转化。然后考虑题求得很想最长上升子序列,而最长上升子序列有一种 \(O(nlogn)\)做法,即记录前一个数是几的最大值,本题很类似,与前一个数和前一差值有关,所以定义 \(f[i][j]\) 表示前一个数是 \(i\),差值为j最大距离。直接更新即可。

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,a[N],res[10],dp[10][10];
int md(int x)
{
	if(x>=0)return x%3;
	else return x=-2*x,x%3;
}
int main()
{
	freopen("sequence.in","r",stdin); 
	freopen("sequence.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];
		a[i]=md(a[i]);
	}
	dp[a[1]][0]=1;
	for(int i=2;i<=n;i++)
	{
		for(int las=0;las<=2;las++)
		{
			int c=md(a[i]-las);
			for(int cj=c;cj>=0;cj--)res[c]=max(res[c],dp[las][cj]+1);
		}		
		for(int c=0;c<=2;c++)
		{
			dp[a[i]][c]=max(dp[a[i]][c],res[c]);
			res[c]=0;
		}
		dp[a[i]][0]=max(dp[a[i]][0],1);
	}
	int ans=min(2,n);
	for(int i=0;i<=2;i++)
		for(int j=0;j<=2;j++)
			ans=max(ans,dp[i][j]);
	cout<<ans<<'\n';
	return 0;
} 

反思:
考场上写出来了,算是理解到了的。\(dp\) 状态的设计一定是有转移中有用的信息决定的。

T2组队参赛

原题链接
算法:dp
先有一些性质,已知\(a_i\)越小越容易满足,所以先按\(a_i\)排序,考虑做出最多题的某一种方案一定是满足前缀。所以设 \(f[i]\) 表示用前 \(i\) 个数满足前 \(i\) 个人可以分得最大组数(不考虑后面的数)。有 \(f[i]=max_{j<=i-a[i]}(f[j])+1\),所以总组数为\(n+f[i]-i\),但如果i<a[i]就无意义了,只能用后面的数来满足,所以 \(f[i]=0\),总组数为 \(n-a[i]+1\)。所以分情况转移即可。

#include <bits/stdc++.h>
using namespace std;
const int N=3e5+10;
int n,q,a[N],b[N],f[N],ans[N],g[N];
int main()
{
//	freopen("xcpc.in","r",stdin);
//	freopen("xcpc.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];
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++)
	{
		if(a[i]<=i)f[i]=f[i-a[i]]+1,g[i]=n-i+f[i];
		else f[i]=0,g[i]=n-a[i]+1;
		f[i]=max(f[i-1],f[i]);
		ans[g[i]]=i;
	}
	for(int i=n;i>=1;i--)ans[i]=max(ans[i+1],ans[i]);
	cin>>q;
	for(int i=1;i<=q;i++)	
	{
		int x;cin>>x;
		cout<<ans[x]<<'\n'; 
	}
	return 0;
} 

反思:
没有想到dp方面,主要是连第一步的转化都没想到,所以要多挖掘题目性质,简化题目。

T3游戏(填坑)

叫游戏的题就没做出来过!!!

T4交换比特

还是要先推性质。考虑 \(n=2\) 的情况,只有四种可能\(2112,1221,1212,2121\) 前两种转化为\(1122,2211\) 都可以,但后两种则只能分别转化为 \(1122\) 和 \(2211\) 来满足最小步数,所以
形式化的来说,如果 \(l[i]<l[j]\) 并且 \(r[i]<r[j]\) 则 \(i\) 一定在 \(j\) 以前(\(l[i]\) 表示i第一次出现,\(r[i]\) 表示第二次出现)。所以我们可以从 \(i\) 向 \(j\) 连边,跑topu即可。但考虑连边的最坏时间复杂度为 \(O(n^2)\),所以要优化建图。因为连边的限制是二维偏序,所以用cdq优化建图。

#include <bits/stdc++.h>
using namespace std;
const int N=2e7+10; 
int n,a[N],tot,cnt,nxt[N],hd[N],go[N],in[N],xd[N],l[N],R[N];
struct node
{
	int id,ll,rr;
}b[N],jz[N];
bool cmp(node x,node y)
{
	return x.ll<y.ll;
} 
void add(int x,int y)
{
	nxt[++tot]=hd[x];go[tot]=y;in[y]++;hd[x]=tot;
	return;
} 
void solve(int l,int r)
{
	if(l==r)return ;
	int mid=(l+r)>>1;
	solve(l,mid);solve(mid+1,r);
	int jcnt=cnt;
	for(int i=mid+1;i<=r;i++)
	{
		xd[i]=++cnt;//右边的每个点建虚点出来
		add(cnt,b[i].id); //虚点向原点连边
	}
	for(int i=mid+1;i<r;i++)add(xd[i],xd[i+1]);//虚点之间连边,前缀优化。
	int x=l,j=mid+1,i=l;bool flag=0;
	for(;i<=mid;i++)
	{
		while(j<r&&b[j].rr<b[i].rr)jz[x++]=b[j],j++;
		if(flag==0&&j==r&&b[i].rr>b[j].rr)jz[x++]=b[j],flag=1;
		if(b[i].rr<b[j].rr)add(b[i].id,xd[j]);//左边的点向右边的第一个r[j]>r[i]的点的虚点连边
		jz[x++]=b[i];
	}
	if(j<=r)jz[x++]=b[j];
	for(int i=l;i<=r;i++)b[i]=jz[i];
	return; 
}
queue<int> q;
priority_queue<int,vector<int>,greater<int> > qx;
int main()
{
	freopen("swap.in","r",stdin);
	freopen("swap.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n;
	for(int i=1;i<=2*n;i++)
	{
		cin>>a[i];
		if(l[a[i]]==0)l[a[i]]=i;
		else R[a[i]]=i;
	}
	for(int i=1;i<=n;i++)
	{
		b[i].id=i;b[i].ll=l[i];b[i].rr=R[i];
	}
	cnt=n;
	sort(b+1,b+n+1,cmp);
	solve(1,n);
	for(int i=1;i<=n;i++)
		if(!in[i])qx.push(i);
	for(int i=n+1;i<=cnt;i++)
		if(!in[i])q.push(i);
	while(!q.empty()||!qx.empty())
	{
		int u;
		if(!q.empty())
		{
			u=q.front();q.pop();
		}
		else
		{
			u=qx.top();qx.pop();
			cout<<u<<" "<<u<<" "; 
		} 
		for(int i=hd[u];i;i=nxt[i])
		{
			int v=go[i];
			in[v]--;
			if(in[v]==0)
			{
				if(v<=n)qx.push(v);
				else q.push(v);
			}
		} 
	}
	return 0;
} 

反思:性质没推出来,虽然即使推出来也不会用优化建图,改题理解的还是比较深刻,建图优化一定是根据性质选择。

10.21noip模拟赛二

T1 致敬传奇捆绑测试题目

算法:贪心,打表
打表找规律题,显然最优方案是\(3,1,2,4,5...\),除了前三位,性质很优美,全部异或在一起,偶数一定是会$4\oplus6\oplus8\oplus10.. $所以显然有规律,直接打表,就没有然后了。(也可以拆位做,或数学推导)

#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll n,ans,k,jg[10]={0,0,6,4,0,0,2,0};
int main()
{
	freopen("perm.in","r",stdin);
	freopen("perm.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n;
	if(n==1||n==2){
		cout<<"2"<<'\n';
		return 0;
	} 
	if(n==3){
		cout<<"3"<<'\n';
		return 0;
	}
	n-=4;
	int x=n%8;
	if(x!=0&&x!=4&&x!=1&&x!=5)cout<<jg[x]<<'\n';
	else if(x==0||x==1) cout<<2ll*(n-x+5)<<'\n'; 
	else if(x==4||x==5)	cout<<2ll*(n-x+11)<<'\n';		
	return 0;
 } 

反思:数学推导一直推不出来,一个半小时才打表发现规律,下次根据题目难度选推导或打表。

T2 串串

算法:dp
因为要求的答案为极差,直接dp不好做,所以需要钦定最大值和最小值,一共只有26个字母,所以定义 \(dp[i][j]\) 表示 \(i\) 的数量最多,\(j\) 的数量最少的最大权值差。但考虑转移出的结果有可能根本没选 \(j\),所以加一维限制表示是否选了 \(j\)。时间复杂度为\(O(26^2n)\),但考虑只有等于 \(i\) 或 等于 \(j\) 时对 \(dp[i][j][0/1]\) 有改变。所以只用 \(O(52n)\) 即可。

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10; 
int n,ans,col[30],f[30][30][2];
char s[N];
int main()
{
	freopen("range.in","r",stdin);
	freopen("range.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n>>s;
	for(int i=0;i<26;i++)
		for(int j=0;j<26;j++)
			f[i][j][1]=-2;
	for(int i=0;i<n;i++)
	{
		int  x=s[i]-'a';
		for(int j=0;j<26;j++)
		{
			if(j==x)continue;
			f[x][j][0]++;
			if(f[x][j][1]!=-2)f[x][j][1]++;
			f[j][x][1]=max(max(f[j][x][1],f[j][x][0])-1,-1);//只选一个x,为-1,对f[x][j]有用。 
			f[j][x][0]=0; 
			ans=max(ans,max(f[j][x][1],f[x][j][1])); 
		}
	}
	cout<<ans<<'\n';
	return 0;
 } 

T3计算几何

还要先推性质,可能造成贡献的只有左边或右边最近的高度小于当前点的点,证明比较简单,如果我们求得结果为 \((i,j)\) 且不是刚才所得类型,则 \((i,l[j])\) 一定更优( \(l[j]\) 表示 \(j\) 左边最近的高度小于当前点的点),因为 \(x[l[j]]-x[i]<x[j]-x[i],w[i]+w[l[j]]<w[i]+w[j]\) 结果所以单调栈求出来。按横坐标排序,反过来的树状数组维护一下即可。

#include <bits/stdc++.h>
using namespace std;
const int N=1e3+10,M=3e5+10;
#define int long long
int n,qq,sh[M],h[M],w[M],ans[M],top,st[M];
vector <int> q[M];
struct node
{
	int l,id;
};
vector<node> qu[M];
int lowbit(int x){return x&-x;}
void modify(int x,int zhi)
{
	while(x)
	{
		sh[x]=min(sh[x],zhi);
		x-=lowbit(x);
	}
}
int query(int x)
{
	int res=9e18;
	while(x<=n)
	{
		res=min(res,sh[x]);
		x+=lowbit(x);
	}
	return res;
}
signed main()
{
//	freopen("geo.in","r",stdin);
//	freopen("geo.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n>>qq;
	for(int i=1;i<=n;i++)cin>>h[i]>>w[i],sh[i]=9e18;
	for(int i=1;i<=n;i++)
	{
		while(top&&w[st[top]]>w[i])top--;
		if(top)q[i].push_back(st[top]);
		st[++top]=i;
	}
	top=0;
	for(int i=n;i>=1;i--)
	{
		while(top&&w[st[top]]>w[i])top--;
		if(top)q[st[top]].push_back(i);
		st[++top]=i;
	}	
	for(int i=1;i<=qq;i++)
	{
		int l,r;cin>>l>>r;
		qu[r].push_back((node){l,i});
	}
	for(int i=1;i<=n;i++)
	{
		for(auto u:q[i]) 
			modify(u,1ll*(h[i]-h[u])*(w[i]+w[u]));
		for(auto u:qu[i]) 
			ans[u.id]=query(u.l);
	}
	for(int i=1;i<=qq;i++)cout<<ans[i]<<'\n';
	return 0;
 } 

T4消消乐(待填)

10.22noip模拟赛三

T1 链链链

算法:贪心
贪心一:正向思考,最大值一定会跟其它点分开,将它与先分开一定是最优的,所以每次找最大值即可。(st表)
贪心二:反向思考,合并时先将小的合并到左右两边的大值上一定最优,每次选代价小的即可。(链表)
还可以 \(o(n)\) dp。

#include <bits/stdc++.h>
using namespace std;
const int N=2e5+10;
#define ll long long
int c,t,n;
ll ans;
struct node
{
	int id;ll zhi;
}a[N];
bool cmp(node x,node y)
{
	return x.zhi<y.zhi;
}
struct lb
{
	int nxt,pre;
	ll mx,zhi;
}b[N];
int main()
{
	freopen("chain.in","r",stdin);
	freopen("chain.out","w",stdout); 
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>c>>t;
	while(t--)
	{
		cin>>n;ans=0;
		for(int i=1;i<=n;i++)cin>>a[i].zhi,a[i].id=i;
		sort(a+1,a+n+1,cmp);
		b[0].mx=0;
		for(int i=1;i<=n;i++)
		{
			b[a[i].id].zhi=a[i].zhi;
			if(a[i].zhi==a[i-1].zhi)b[a[i].id].mx=b[a[i-1].id].mx;
			else b[a[i].id].mx=b[a[i-1].id].mx+1;
		}
		for(int i=1;i<=n;i++)b[i].nxt=i+1,b[i].pre=i-1;	
		b[0].nxt=1,b[n+1].pre=n;
		b[0].mx=b[n+1].mx=b[0].zhi=b[n+1].zhi=0x3f3f3f3f;
		for(int i=1;i<n;i++)
		{	
			int cur=a[i].id; 
			ll zb=abs(b[b[cur].pre].zhi-b[cur].zhi),yb=abs(b[b[cur].nxt].zhi-b[cur].zhi);
			ans+=min(zb,yb);
			b[b[cur].pre].nxt=b[cur].nxt;
			b[b[cur].nxt].pre=b[cur].pre;
		}
		cout<<ans<<'\n';
	}
	return 0;
} 

反思:只会第一题,还自己给自己增加了一个 \(n\) 的复杂度,挂了30。写题前应该先理清思路,在可能的范围内选择最优最简单的做法

T2

T3

T4

标签:10,10.22,int,top,cin,10.19,考试,freopen,dp
From: https://www.cnblogs.com/storms11/p/18495969

相关文章

  • 炼石 plan 10.19
    T1--平方数对(sqrt)把\(\sqrtx\)化成\(o\sqrt\alpha\)的形式,\((\sqrtA+\sqrtB)^2\inN\)当且仅当\(\alpha_A=\alpha_B\),那记一下\(\alpha=x\)的\(A/B\)即可求出答案。#include<bits/stdc++.h>#defineintlonglong#defineup(i,l,r)for(inti=l;i<......
  • [考试总结] 2024.10.23 最近的几场考试
    从2024.10.14考图论起。2024.10.14考图论T1转前缀和,跑差分约束或者贪心,贪心用[树状数组、并查集](?)实现。注意前缀和的额外限制(差分约束)、贪心实现的正确性。T2相当于连无向边,两点连通就能得到差。注意到没必要连接两个已经连通的点,于是会形成一棵树。带权并查集或者用......
  • SpringBoot养老知识考试管理系统-计算机毕业设计源码86305
    摘要随着人口老龄化趋势的加剧,老年人的健康管理和养老知识学习变得尤为重要。然而,传统的养老知识教育方式存在信息不对称、资源有限等问题,无法满足老年人广泛的学习需求。因此,本系统旨在利用互联网技术,为老年人提供便捷的养老知识学习和考试平台,帮助他们掌握养老知识、提高健......
  • [技巧] 联考策略 2024.10.22
    (2024.10.22;我目前的水平)题目难度&我目前的水平T1:应当较快地做出来。但我目前很可能会在T1上花非常多时间(2h;最近两场考试);甚至做不出T1。T2:应当做出来。思维难度也许比T1低(最近两场考试),但可能还是T1要简单一些(毕竟[机房里T1得分比T2高些](?))。T3:可以尝试写部分分&......
  • MySQL DQL 10.22
    --一基础查询--1查询多个字段--SELECT字段列表FROM表名 ;--SELECT*FROM表名;--查询所有数据--2去除重复记录--SELECTDISTINCT字段列表FROM表名;--3起别名--AS--AS也可以省略--selectname,sexas性别fromstu;--selectDISTINCTnamefromstu......
  • 10.22随笔,二叉树求度为一的节点的个数
    今天去健身房锻炼了身体这是关于二叉树如何求度为一的节点的个数,同理还能求度为零和二的,不难。还又复习了一遍前序中序后续的遍历方法,已经可以由任意两种推出二叉树结构了,不过二叉树的样子和模式我还是有点不太能和代码结合去理解,还需要多加练习include<stdio.h>include<std......
  • 10.22 课程内容总结
    本节课学习进一步运用AI生成一份完整、独特、符合自己需要的个性化教案。以下为课程中设计到的提示语以及思维导图和PPT生成工具。提示语设计:·提示语设计,是指用户设计提供给生成式人工智能大模型的一段文字,AI根据这些文本生成回应内容。·提示语如何设计,决定了AI生成内容的质......
  • 2024.10.22 鲜花
    列表题解你从未离去浩瀚星空里只剩你的背影银河已凝结成冰记忆滑过泪滴想象能回到过去终会存在我心底虽然逃避她消失在梦里日出的幻境再次感觉到你风送来你的呼吸月色倒映着惊喜原来你从未离去默默守护在这里无声无息如影随形我不再迷茫思念是唯一的行囊漫......
  • 2024.10.22训练记录
    上午NOIP模拟赛最近每天上午都是模拟赛了,感觉每打一场信心都少了。确实有全力认真打,\(4\)个小时不是磨洋工过去的,但是有时候就是不能想出来。思维题也太电波了。A很厉害的dp技巧题,基本是会这个trick就会吧。\(O(nm)\)的复杂度可以过掉这个弱化版。对于几个数加起来有固......
  • 2024.10.22模拟赛反思
    2024.10.22模拟赛反思怎么感觉题目越简单打的越差啊?\(T1\)没什么好说的,\(8\)分钟就做完了。主要问题主要就是在\(T2\)上。其实本来\(10\min\)就想到贪心怎么做了,但是发现直接贪心有点问题,所以就一直在想怎么解决。可能是前几场比赛考的比较难的缘故,我就一直在想能不能用......