2018.09.16(八校聯考)
阿新 • • 發佈:2018-12-10
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
大概就是列舉最高點,三分高度,然後用樹狀陣列來維護前後貢獻
辣雞南瓜碼力不足