NOIP前刷水行动
Posted ACist
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NOIP前刷水行动相关的知识,希望对你有一定的参考价值。
2016.11.15
BZOJ1009:DP+矩阵乘法+KMP
BZOJ1898:矩阵乘法
BZOJ4101:贪心,考虑我们往右边撞的时候,我们会向左边冲
,于是枚举答案点利用一个指针计算即可!
2016.11.14
OI队内测试
2016.11.13
BZOJ4512:乱搞
BZOJ4102:DP+bfs
BZOJ4395:bfs
BZOJ3889:双键值最短路
BZOJ4512 #include <bits/stdc++.h> using namespace std; #define LL long long int N,sx,sy,ans; char s[1020]; bool vis[2020][2020],north[2020][2020],east[2010][2010]; int main(){ // freopen("data.in","r",stdin); // freopen("A.out","w",stdout); scanf("%d%s",&N,s); sx=sy=1010; for (int i=0;i<N;i++){ vis[sx][sy]=1; char ch=s[i]; if (ch==\'N\'){ sy++; if (!north[sx][sy-1]&&vis[sx][sy])ans++; north[sx][sy-1]=1; } if (ch==\'S\'){ sy--; if (!north[sx][sy]&&vis[sx][sy])ans++; north[sx][sy]=1; } if (ch==\'E\'){ sx++; if (!east[sx-1][sy]&&vis[sx][sy])ans++; east[sx-1][sy]=1; } if (ch==\'W\'){ sx--; if (!east[sx][sy]&&vis[sx][sy])ans++; east[sx][sy]=1; } } printf("%d\\n",ans); } BZOJ4102 #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> #include<queue> #define ll long long #define ld long double #define N 1005 #define M N*(N+1) using namespace std; int n,p,tot; int pre[M],v[M],now[N],f[N],dis[N][N]; bool vis[N]; queue<int>q; struct data{ int val,pos; }a[N]; int read() { int x=0,f=1; char ch; while (ch=getchar(),ch<\'0\'||ch>\'9\') if (ch==\'-\') f=-1; while (x=x*10+ch-\'0\',ch=getchar(),ch>=\'0\'&&ch<=\'9\'); return x*f; } void ins(int a,int b){++tot; pre[tot]=now[a]; now[a]=tot; v[tot]=b; } bool cmp(data a,data b){return a.val<b.val; } void bfs(int u) { memset(vis,0,sizeof(vis)); q.push(u); dis[u][u]=0; vis[u]=1; while (!q.empty()) { int x=q.front(); q.pop(); for (int p=now[x]; p; p=pre[p]) { int son=v[p]; if (!vis[son]) { dis[u][son]=dis[u][x]+1; q.push(son); vis[son]=1; } } } } int main() { n=read(); p=read(); for (int i=1; i<=n; i++) { int x=read(),d=read(); a[i].val=x; a[i].pos=i; for (int j=1; j<=d; j++) {int y=read(); ins(i,y); ins(y,i);} } for (int i=1; i<=n; i++) bfs(i); sort(a+1,a+n+1,cmp); for (int i=1; i<=n; i++) f[i]=a[i].val; for (int i=1; i<=n; i++) for (int j=1; j<=i-1; j++) { if (a[i].val>a[j].val && dis[a[i].pos][a[j].pos]) { f[i]=max(f[i],f[j]-dis[a[i].pos][a[j].pos]*p+a[i].val); } } int ans=0; for (int i=1; i<=n; i++) ans=max(ans,f[i]); printf("%d\\n",ans); return 0; } BZOJ4395 #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> #include<queue> #define ll long long #define ld long double #define N 205 #define M 40005 using namespace std; int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0}; int pre[M],v[M],now[N*N],tot; int n,m,ans; queue<int>q; bool vis[N][N],lig[N][N]; int read() { int x=0,f=1; char ch; while (ch=getchar(),ch<\'0\'||ch>\'9\') if (ch==\'-\') f=-1; while (x=x*10+ch-\'0\',ch=getchar(),ch>=\'0\'&&ch<=\'9\'); return x*f; } int encode(int a,int b){return (a-1)*n+b; } void ins(int a,int b){ ++tot; pre[tot]=now[a]; now[a]=tot; v[tot]=b; } int main() { n=read(); m=read(); for (int i=1; i<=m; i++) { int a=read(),b=read(),c=read(),d=read(); ins(encode(a,b),encode(c,d)); } int last=1; ans=1; for (;;) { q.push(encode(1,1)); memset(vis,0,sizeof(vis)); vis[1][1]=1; lig[1][1]=1; while (!q.empty()) { int pp=q.front(),x,y; q.pop(); //last++; for (int p=now[pp]; p; p=pre[p]) { int son=v[p]; x=(son-1)/n+1,y=(son-1)%n+1; if (!lig[x][y]) lig[x][y]=1,ans++; } x=(pp-1)/n+1,y=(pp-1)%n+1; for (int i=0; i<4; i++) { int xx=x+dx[i],yy=y+dy[i]; if (xx<1 || xx>n || yy<1 || yy>n || !lig[xx][yy] || vis[xx][yy]) continue; vis[xx][yy]=1; q.push(encode(xx,yy)); } } if (last==ans) break; last=ans; } printf("%d\\n",ans); return 0; } BZOJ3889 #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> #include<queue> #define ll long long #define ld long double #define inf 100000000000000 #define N 1005 using namespace std; int s,t,m,n; ll a[N][N],b[N][N],dis[N],d[N]; int c[N]; bool vis[N]; queue<int>q; int read() { int x=0,f=1; char ch; while (ch=getchar(),ch<\'0\'||ch>\'9\') if (ch==\'-\') f=-1; while (x=x*10+ch-\'0\',ch=getchar(),ch>=\'0\'&&ch<=\'9\'); return x*f; } void spfa() { for (int i=1; i<=m; i++) dis[i]=inf; dis[s]=d[s]=0; vis[s]=1; q.push(s); while (!q.empty()) { int x=q.front(); q.pop(); vis[x]=0; //cout<<" "<<x<<endl; for (int i=1; i<=m; i++) { // cout<<i<<" "<<dis[i]<<" "<<dis[x]<<" "<<a[x][i]<<endl; if (dis[i]>dis[x]+a[x][i] || ((dis[i]==dis[x]+a[x][i]) && d[i]>d[x]+b[x][i])) { // cout<<" "<<x<<" "<<i<<" "<<a[x][i]+dis[x]<<endl; dis[i]=dis[x]+a[x][i]; d[i]=d[x]+b[x][i]; if (!vis[i]) vis[i]=1,q.push(i); } } //|| (dis[i]==dis[x]+a[x][i] && d[i]>d[x]+b[x][i]) } } int main() { s=read(); t=read(); n=read(); for (int i=1; i<=1000; i++) for (int j=1; j<=1000; j++) a[i][j]=inf; for (int i=1; i<=n; i++) { int len=read(),cnt=read(); for (int j=1; j<=cnt; j++) c[j]=read(),m=max(m,c[j]); for (int j=1; j<=cnt; j++) for (int k=j+1; k<=cnt; k++) if (a[c[j]][c[k]]>len || ((a[c[j]][c[k]]==len) && (b[c[j]][c[k]]>(k-j)))) a[c[j]][c[k]]=len,b[c[j]][c[k]]=k-j; } spfa(); if (dis[t]==inf) dis[t]=-1,d[t]=-1; cout<<dis[t]<<" "<<d[t]<<endl; return 0; }
2016.11.12
BZOJ3887: spfa(正边一次+反边一次)
BZOJ3886:状态压缩dp+二分(f[i]表示看电影状态为i的最长连续时间)
BZOJ4098:DP优化(f[i][j][k][l]:(i+j)==(k+l) 优化为f[i][j][k]:(i+j)满足滚动数组
BZOJ3888:把时间求出来+线段树
BZOJ3887 #include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<queue> #define N 100005 #define M 200005 using namespace std; int read() { int x=0,f=1; char ch; while (ch=getchar(),ch<\'0\'||ch>\'9\') if (ch==\'-\') f=-1; while (x=x*10+ch-\'0\',ch=getchar(),ch>=\'0\'&&ch<=\'9\'); return x*f; } int n,m; int a[N],b[N]; int tot,pre[M],v[M],now[N]; int bel[N],low[N],dfn[N],num[N],total,ind,top,z[N]; int dist1[N],dist2[N]; bool inq[N],vis[N]; queue<int> q; void ins(int a,int b){++tot; pre[tot]=now[a]; now[a]=tot; v[tot]=b;} void tarjan(int x) { low[x]=dfn[x]=++ind; ++top; z[top]=x; inq[x]=1; for (int p=now[x]; p; p=pre[p]) { int son=v[p]; if (!dfn[son]) tarjan(son),low[x]=min(low[x],low[son]); else if (inq[son]) low[x]=min(low[x],dfn[son]); } if (low[x]==dfn[x]) { ++total; num[total]=1; inq[x]=0; bel[x]=total; while (z[top]!=x) { int son=z[top]; bel[son]=total; inq[son]=0; num[total]++; top--; } top--; } } void build(int X) { memset(now,0,sizeof(now)); tot=0; for (int i=1; i<=m; i++) { int x=a[i],y=b[i]; if (bel[x]!=bel[y]) { if (X==1) ins(bel[x],bel[y]); else ins(bel[y],bel[x]); } } } void spfa1() { vis[bel[1]]=1; dist1[bel[1]]=num[bel[1]]; q.push(bel[1]); while (!q.empty()) { int x=q.front(); q.pop(); vis[x]=0; for (int p=now[x]; p; p=pre[p]) { int son=v[p]; if (dist1[son]<dist1[x]+num[son]) { dist1[son]=dist1[x]+num[son]; if (!vis[son]) q.push(son),vis[son]=1; } } } } void spfa2() { vis[bel[1]]=1; dist2[bel[1]]=num[bel[1]]; q.push(bel[1]); while (!q.empty()) { int x=q.front(); q.pop(); vis[x]=0; for (int p=now[x]; p; p=pre[p]) { int son=v[p]; if (dist2[son]<dist2[x]+num[son]) { dist2[son]=dist2[x]+num[son]; if (!vis[son]) q.push(son),vis[son]=1; } } } } int main() { n=read(); m=read(); for (int i=1; i<=m; i++) a[i]=read(),b[i]=read(),ins(a[i],b[i]); for (int i=1; i<=n; i++) if (!dfn[i]) tarjan(i); build(1); spfa1(); build(2); spfa2(); int ans=0; for (int i=1; i<=m; i++) if (bel[a[i]]!=bel[b[i]] && dist1[bel[b[i]]] && dist2[bel[a[i]]]) { ans=max(ans,dist1[bel[b[i]]]+dist2[bel[a[i]]]-num[bel[1]]); } printf("%d\\n",ans); return 0; } BZOJ3886 #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> using namespace std; int n,L; int num[25],len[25],c[25][1005]; int f[1100000]; int read() { int x=0,f=1; char ch; while (ch=getchar(),ch<\'0\'||ch>\'9\') if (ch==\'-\') f=-1; while (x=x*10+ch-\'0\',ch=getchar(),ch>=\'0\'&&ch<=\'9\'); return x*f; } int find(int x,int s) { int l=1,r=num[x],Ans=-1; while (l<=r) { int mid=(l+r)>>1; if (c[x][mid]<=s) Ans=mid,l=mid+1; else r=mid-1; } return Ans; } int main() { n=read(); L=read(); for (int i=1; i<=n; i++) { len[i]=read(); num[i]=read(); for (int j=1; j<=num[i]; j++) c[i][j]=read(); } f[0]=0; int s=1<<n,ans=0x7fffffff; for (int i=1; i<s; i++) f[i]=-1; for (int i=0; i<s; i++) { if (f[i]==-1) continue; int k=0; if (f[i]>L) { for (int j=i; j; j>>=1) if (j&1) k++; ans=min(ans,k); continue; } for (int j=1; j<=n; j++) { if (i&(1<<(j-1))) continue; int k=find(j,f[i]); if (k==-1) continue; f[i|(1<<(j-1))]=max(f[i|(1<<(j-1))],c[j][k]+len[j]); } } if (ans==0x7fffffff) ans=-1; printf("%d\\n",ans); return 0; } BZOJ4098 #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> #define N 505 #define mod 1000000007 #define add(a,b) (a=(a+b)%mod) using namespace std; int n,f[2][N][N]; char s[N][N]; int main() { scanf("%d",&n); for (int i=1; i<=n; i++) scanf("%s",s[i]+1); if(s[1][1]!=s[n][n]) { puts("0"); return 0; } int now=1,last=0; f[now][0][0]=1; for (int h=0; h<n; h++) { now^=1; last^=1; memset(f[now],0,sizeof(f[now])); for (int i=0; i<=h; i++) { int j=(h-i),a=i+1,b=j+1; for (int k=0; k<=h; k++) { int l=h-k,x=n-l,y=n-k; /* if (s[a+1][b]==s[x][y-1]) (f[now][i+1][k+1]+=f[last][i][k])%mod; if (s[a+1][b]==s[x-1][y]) (f[now][i+1][k]+=f[last][i][k])%mod; if (s[a][b+1]==s[x][y-1]) (f[now][i][k+1]+=f[last][i][k])%mod; if (s[a][b+1]==s[x-1][y]) (f[now][i][k]+=f[last][i][k])%mod; */ if(s[a+1][b]==s[x-1][y])add(f[now][i+1][ k ],f[last][i][k]); if(s[a+1][b]==s[x][y-1])add(f[now][i+1][k+1],f[last][i][k]); if(s[a][b+1]==s[x-1][y])add(f[now][ i ][ k ],f[last][i][k]); if(s[a][b+1]==s[x][y-1])add(f[now][ i ][k+1],f[last][i][k]); } } } int ans=0; for (int i=0; i<n; i++) add(ans,f[last][i][i]); printf("%d\\n",ans); return 0; } BZOJ3888 #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> #define N 50005 using namespace std; int n,tot; struct data{ int h,l,r; }a[N]; int b[2*N],cov[N*8]; int read() { int x=0,f=1; char ch; while (ch=getchar(),ch<\'0\'||ch>\'9\') if (ch==\'-\') f=-1; while (x=x*10+ch-\'0\',ch=getchar(),ch>=\'0\'&&ch<=\'9\'); return x*f; } bool cmp2(data a,data b){return a.h<b.h; } int get(int x,int c) { return x>=0?0:-x*c; } int cover(int k,int l,int r,int x,int y) { if (cov[k]) return 0; if (x<=l && r<=y) { cov[k]=1; return 1; } bool ret=0; int mid=(l+r)>>1; if (x<=mid) ret|=cover(k*2,l,mid,x,y); if (mid<y) ret|=cover(k*2+1,mid+1,r,x,y); cov[k]=cov[k*2]&cov[k*2+1]; return特别行动队题解