1. 程式人生 > >2018.09.16(八校聯考)

2018.09.16(八校聯考)

T1

考試時用了個神學做法水了85分,um其實和標答也就一個vecto/set的區別,資料可能是腳造的8

先預處理翻轉前的固定點做字首和,然後列舉對稱軸,由內向外進行更新

然後就是,set的優先順序和priority_queue相反的,然後過載運算子的時候不用反著來

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <set>
#define maxn 1000010
using namespace std;

int n,ans,a[maxn],sum[maxn];

int read()
{
	int xx=0,kk=1;char ch=' ';
	while(!isdigit(ch)){ch=getchar();if(ch=='-')kk=-1;}
	while(isdigit(ch)){xx=xx*10+ch-'0';ch=getchar();}
	return kk*xx;
}

struct node
{
	int i,ai;
	node(int i,int ai):i(i),ai(ai){};
	bool operator <(const node&a)const
	{
		return max(i,ai)<max(a.i,a.ai);
	}
};
multiset<node> v[maxn<<1];

int main()
{
	freopen("rotate.in","r",stdin);
	freopen("rotate.out","w",stdout);
	n=read();
	for(int i=1;i<=n;++i)
		a[i]=read(),v[a[i]+i].insert((node(i,a[i])));
	for(int i=1;i<=n;++i)
	    sum[i]=sum[i-1]+(a[i]==i);
	for(int i=1;i<=2*n;++i)
	{
		int tmp=0;
		while(v[i].size())
		{
			tmp++;
			node now=*v[i].begin();
			v[i].erase(v[i].begin());
			int maxi=max(now.i,now.ai);
			int mini=min(now.i,now.ai);
			ans=max(ans,sum[mini-1]+tmp+sum[n]-sum[maxi]);
		}
	}
	printf("%d",ans);
	return 0;
}
/*
12
10 9 8 4 6 5 7 3 2 1 12 11
*/

T2

比較有意思的最短路問題,考試的時候太sb了,沒有考慮到周圍都沒有牆的情況,直接bfs居然還得了25...

考慮四周沒有牆的情況其實就是往這個點上下左右的格子連長1的邊,然後上下左右的牆連一條長dis+1的邊,其中dis就等於這個格子到其上下左右的牆的最短距離

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <queue>
#define inf 1e9
#define maxn 520
#define maxm 250100
using namespace std;

char ch[maxn]; 
int n,m,num,s,t;
bool vis[maxm],obs[maxm];
int l[maxm],r[maxm],u[maxm],d[maxm],dis[maxm],fir[maxm];

struct qwq
{
	int nxt,to,val;
}e[maxm<<3];

struct qvq
{
	int u,d;
	bool operator <(const qvq&a)const
	{
		return d>a.d;
	}
};
priority_queue<qvq> q;

int getnum(int i,int j)
{
	return (i-1)*m+j;
}

void addedge(int u,int v,int w)
{
	e[++num].to=v;
	e[num].val=w;
	e[num].nxt=fir[u];
	fir[u]=num;
}

void dijkstra(int s)
{
	for(int i=1;i<=n*m;++i) dis[i]=inf;
	dis[s]=0,q.push((qvq){s,dis[s]});
	while(!q.empty())
	{
		qvq sx=q.top();q.pop();
		int u=sx.u,d=sx.d;
		if(dis[u]!=d) continue;
		for(int i=fir[u];i;i=e[i].nxt)
		{
			int v=e[i].to;
			if(dis[u]+e[i].val<dis[v])
			{
				dis[v]=dis[u]+e[i].val;
				q.push((qvq){v,dis[v]});
			}
		}
    }
	
}

int main()
{
	freopen("cell.in","r",stdin);
	freopen("cell.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)
	{
		scanf("%s",ch+1);
		for(int j=1;j<=m;++j)
		{
			if(ch[j]=='#') obs[getnum(i,j)]=true;
			if(ch[j]=='C') s=getnum(i,j);
			if(ch[j]=='F') t=getnum(i,j);
		}
	}
	for(int i=1;i<=n;++i)
	for(int j=1;j<=m;++j)
	{
		l[getnum(i,j)]=r[getnum(i,j)]=j;
		u[getnum(i,j)]=d[getnum(i,j)]=i;
	} 
	for(int i=2;i<=n;++i)
    for(int j=1;j<=m;++j)
	    if(!obs[getnum(i-1,j)]) u[getnum(i,j)]=u[getnum(i-1,j)];
	for(int i=n-1;i>=1;--i)
	for(int j=1;j<=m;++j)
	    if(!obs[getnum(i+1,j)]) d[getnum(i,j)]=d[getnum(i+1,j)];
	for(int i=1;i<=n;++i)
	for(int j=2;j<=m;++j)
	    if(!obs[getnum(i,j-1)]) l[getnum(i,j)]=l[getnum(i,j-1)];
	for(int i=1;i<=n;++i)
	for(int j=m-1;j>=1;--j)
	    if(!obs[getnum(i,j+1)]) r[getnum(i,j)]=r[getnum(i,j+1)];;
	for(int i=1;i<=n;++i)
	for(int j=1;j<=m;++j)
	{
		if(obs[getnum(i,j)]) continue;
		if(i>1&&!obs[getnum(i-1,j)])addedge(getnum(i,j),getnum(i-1,j),1);
		if(i<n&&!obs[getnum(i+1,j)])addedge(getnum(i,j),getnum(i+1,j),1);
		if(j>1&&!obs[getnum(i,j-1)])addedge(getnum(i,j),getnum(i,j-1),1);
		if(j<m&&!obs[getnum(i,j+1)])addedge(getnum(i,j),getnum(i,j+1),1);
		int dis=min(min(j-l[getnum(i,j)],r[getnum(i,j)]-j),min(i-u[getnum(i,j)],d[getnum(i,j)]-i));
		addedge(getnum(i,j),getnum(i,l[getnum(i,j)]),dis+1);
		addedge(getnum(i,j),getnum(i,r[getnum(i,j)]),dis+1);
		addedge(getnum(i,j),getnum(u[getnum(i,j)],j),dis+1);
		addedge(getnum(i,j),getnum(d[getnum(i,j)],j),dis+1);
	}
	dijkstra(s);
	if(dis[t]==inf) puts("no");
	else printf("%d",dis[t]);
	return 0;
}
/*
6 8
########
#.##..F#
#C.##..#
#..#...#
#.....##
########
*/

T3

大概就是列舉最高點,三分高度,然後用樹狀陣列來維護前後貢獻

辣雞南瓜碼力不足