• 「考试」大假期集训模拟15


    反思

    • 做过的题一定要看,写的博客一定要看
    • 数据范围一定得注意,尤其是有时候他考试中途更新……
    • 见题还是一定要尽量写点东西出来……

    题目简述

    T1 猫和狗

    太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了太丢人了
    还认认真真写的笔记走的思路结果考场就这样写挂成5分了
    不说了,题解之前写过,总之丢死人了

    T2 旋转子段

    似乎考场出了正解还是挺自豪的(然而这也改变不了你T1的5分
    以后一定要检查数据范围啊啊啊啊啊啊啊啊啊啊
    (第二天就再犯了。
    咳咳。废话说多了。
    这道题需要求旋转后固定点的最大值,因为只用做一次旋转,我们可以考虑每个点成为固定点需要怎么转
    旋转在这道题里有两个要素:中心,半径
    所以,对于每一个点,我们可以求出他成为固定点需要的旋转中心和半径,对于旋转中心相同的点,他们是可以一起转的,这个时候我们需要考虑旋转半径
    因为每次旋转会影响到被旋转区间内所有的点,如果这个区间里之前就有固定点,经过一次旋转后他就不是固定点了
    因此,我们可以用前缀和处理一个区间内固定点的个数,在判断时,用原来共有的固定点个数加上这次旋转增加的固定点个数,再减去旋转区间内原有的固定点个数,就是旋转后的固定点个数。
    枚举每一个旋转中心和旋转半径,更新答案即可。
    细节:旋转中心可能是两数中间,可以用类似(manacher)的在中间插“板”解决
    另外,(vector)真真真真好用qaq
    code:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define ull unsigned long long
    #define N 500005
    
    ll n;
    ll a[N];
    ll pre[N*2];
    
    /*
    struct node
    {
    	ll ct,r;
    }g[N<<1];
    */
    ll c,r;
    vector<ll> g[N*2];
    
    ll ans=0;
    ll t;
    
    int main()
    {
    	scanf("%lld",&n);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%lld",&a[i]);
    		t=i*2;
    		pre[t-2]=pre[t-3];
    		if(a[i]==i)pre[t-1]=pre[t-2]+1;
    		else pre[t-1]=pre[t-2];
    	}
    	ll all=pre[n*2-1];
    	//for(int i=1;i<=n*2-1;i++)cout<<pre[i]<<' ';cout<<endl;
    	for(int i=1;i<=n;i++)
    	{
    		c=i+a[i]-1;
    		//c=(i*2-1+a[i]*2-1)/2;
    		r=abs(c-a[i]*2+1);
    		//cout<<a[i]<<' '<<c<<' '<<r<<endl;
    		g[c].push_back(r);
    	}
    	for(int i=1;i<=n*2-1;i++)
    	{
    		ll sz=g[i].size();
    		if(!sz)continue;
    		sort(g[i].begin(),g[i].end());
    		for(int j=0;j<sz;j++)
    		{
    			//cout<<i<<' '<<j+1<<' '<<g[i][j]<<' '<<(i-g[i][j]+1)/2<<' '<<(i+g[i][j]+1)/2<<' '<<pre[i+g[i][j]]-pre[i-g[i][j]-1]<<endl;
    			ans=max(ans,(ll)(all+j+1-pre[i+g[i][j]]+pre[i-g[i][j]-1]));
    		}
    	}
    	printf("%lld",ans);
    	return 0;
    }
    

    T3 走格子

    考场上并没有思路,怕不是对搜索题有种天然的畏惧吧……

    传送门的本质就是到四个墙的距离等于到四个墙距离取min
    ——yspm

    我们可以直接暴力预处理出每个非墙位置到上下左右墙的距离,然后相邻格子连边,权值为1,每个位置向上下左右墙前的位置连边,权值为距离的min
    然后在建好的图上跑一个最短路就行了
    (spfa)怎么又忘了……

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long 
    #define ull unsigned long long
    #define N 505
    #define E 2000005
    #define inf 10000000000000000
    #define pll pair<ll,ll>
    #define pq priority_queue
    #define mp make_pair
    
    const ll dx[4]={0,0,1,-1};
    const ll dy[4]={1,-1,0,0};
    
    struct edge
    {
    	ll u,v,w;
    }e[E];
    ll head[E],next[E],tot=0;
    void add(ll a,ll b,ll c)
    {
    	++tot;
    	e[tot].u=a;
    	e[tot].v=b;
    	e[tot].w=c;
    	next[tot]=head[a];
    	head[a]=tot;
    }
    
    ll n,m;
    char ch[N][N];
    ll ma[N][N];
    ll S,T;
    pq<pll > Q;
    
    ll u[N][N],d[N][N],l[N][N],r[N][N];
    ll ud[N][N],dd[N][N],ld[N][N],rd[N][N];
    ll ds[N][N];
    
    inline ll get(ll x,ll y)
    {
    	return x*(m-1)+y;
    }
    /*
    void ins(ll x,ll y,ll w)
    {
    	if(ma[x][y]&&!ds[x][y])
    	{
    		ds[x][y]=w;
    		Q.push(mp(x,y));
    	}
    }
    
    void bfs()
    {
    	pll tmp;
    	while(!Q.empty())
    	{
    		tmp=Q.top();
    		Q.pop();
    		ll x=tmp.first,y=tmp.second;
    		for(int i=0;i<4;i++)
    		{
    			ins(x+dx[i],y+dy[i],ds[x][y]+1);
    		}
    	}
    }*/
    
    void pp()
    {
    	for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
    	{
    		if(!ma[i-1][j])u[i][j]=get(i,j);
    		else u[i][j]=u[i-1][j];
    		if(!ma[i][j-1])l[i][j]=get(i,j);
    		else l[i][j]=l[i][j-1];
    	}
    	for(int i=n;i>=1;i--)for(int j=m;j>=1;j--)
    	{
    		if(!ma[i+1][j])d[i][j]=get(i,j);
    		else d[i][j]=d[i+1][j];
    		if(!ma[i][j+1])r[i][j]=get(i,j);
    		else r[i][j]=r[i][j+1];
    	}
    	for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
    	{
    		if(ma[i][j])ud[i][j]=ud[i-1][j]+1,ld[i][j]=ld[i][j-1]+1;
    		/*else u[i][j]=u[i-1][j];
    		if(!ma[i][j-1])l[i][j]=get(i,j-1);
    		else l[i][j]=l[i][j-1];*/
    	}
    	for(int i=n;i>=1;i--)for(int j=m;j>=1;j--)
    	{
    		if(ma[i][j])dd[i][j]=dd[i+1][j]+1,rd[i][j]=rd[i][j+1]+1;
    		/*if(!ma[i+1][j])d[i][j]=get(i+1,j);
    		else d[i][j]=d[i+1][j];
    		if(!ma[i][j+1])r[i][j]=get(i,j+1);
    		else r[i][j]=r[i][j+1];*/
    	}
    	for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
    	{
    		if(ma[i][j])ds[i][j]=min(min(min(ud[i][j],dd[i][j]),ld[i][j]),rd[i][j]);
    	}
    	for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
    	{
    		if(!ma[i][j])continue;
    		ll now=get(i,j);
    		for(int k=0;k<4;k++)if(ma[i+dx[k]][j+dy[k]])add(now,get(i+dx[k],j+dy[k]),1);
    		add(now,u[i][j],ds[i][j]);
    		add(now,d[i][j],ds[i][j]);
    		add(now,l[i][j],ds[i][j]);
    		add(now,r[i][j],ds[i][j]);
    	}
    }
    
    queue<ll> q;
    ll dis[N*N],vis[N*N];
    ll t;
    void spfa(ll s)
    {
    	for(int i=1;i<=n*m;i++)dis[i]=inf;
    	dis[s]=0;
    	vis[s]=1;
    	q.push(s);
    	while(!q.empty())
    	{
    		t=q.front();
    		q.pop();
    		vis[t]=0;
    		for(int i=head[t];i;i=next[i])
    		{
    			ll v=e[i].v;
    			if(dis[v]>dis[t]+e[i].w)
    			{
    				dis[v]=dis[t]+e[i].w;
    				if(!vis[v])
    				{
    					q.push(v);
    					vis[v]=1;
    				}
    			}
    		}
    	}
    }
    
    int main()
    {
    	//freopen("owo.in","r",stdin);
    	scanf("%lld%lld",&n,&m);
    	for(int i=1;i<=n;i++)scanf("%s",ch[i]+1);
    	
    	for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
    	{
    		if(ch[i][j]=='#')
    		{
    			ma[i][j]=0;
    		//	Q.push(mp(i,j));
    		}
    		else ma[i][j]=1;
    		if(ch[i][j]=='C')S=get(i,j);
    		if(ch[i][j]=='F')T=get(i,j);
    	}
    	pp();
    	//for(int i=1;i<=n;i++){for(int j=1;j<=m;j++)cout<<ds[i][j]<<' ';cout<<endl;}
    	spfa(S);
    	if(dis[T]!=inf)printf("%lld
    ",dis[T]);
    	else puts("no");
    	return 0;
    }
    

    T4 柱状图

    QAQ
    正解:三分
    学长的博客好久才懂的……(侵删

  • 相关阅读:
    c++:资源管理(RAII)、new/delete的使用、接口设计与声明、swap函数
    C++普通链表增删、倒序打印
    Android-UI:按钮监听&文字/图片/进度条&动态变更&dialog&布局&自定义布局/控件/响应事件
    Android-活动生命周期&Bundle回收临时数据&活动启动模式&常用技巧
    C++字符串空格替换题
    C++二维数组查找题
    c++:const、初始化、copy构造/析构/赋值函数
    C++赋值运算符函数
    Android-活动创建&Toast&Menu&Intent
    用yarn代替cnpm,cnpm漏包有点严重
  • 原文地址:https://www.cnblogs.com/zzzuozhe-gjy/p/13448811.html
Copyright © 2020-2023  润新知