summary:38
vijos1002:青蛙跳河。
dp+压缩。距离大于100可以直接%100.然后数据范围小了很多可以dp了。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define clr(x,c) memset(x,c,sizeof(x)) int f[100000]; int a[105]; bool vis[100000]; int main(){ int l,s,t,m; scanf("%d%d%d%d",&l,&s,&t,&m); rep(i,1,m) scanf("%d",&a[i]); sort(a+1,a+m+1); if(s==t){ int ans=0; rep(i,1,m) if(!(a[i]%s)) ans++; printf("%d ",ans);return 0; } int tmp,cnt=0; rep(i,1,m){ if((tmp=a[i]-a[i-1])>100) vis[cnt+=100]=1; else vis[cnt+=tmp]=1; } rep(i,0,cnt+t) f[i]=100;f[0]=0; rep(i,0,cnt+t) rep(j,s,t) if(i>=j) f[i]=min(f[i],f[i-j]+vis[i]); int ans=105; rep(i,cnt,cnt+t) ans=min(ans,f[i]); printf("%d ",ans); return 0; }
vijos1843:货车运输
最大生成树+lca。然而链剖太久没打WA了很久。id和idx容易混淆注意。是最大生成树森林处理一下,将边的权值弄到点的权值上。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define qwq(x) for(edge *o=head[x];o;o=o->next) #define lson x<<1,l,m #define rson x<<1|1,m+1,r int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=20005; const int maxn=100005; const int inf=0x7f7f7f7f; struct edge{ int dist,from,to;edge *next; bool operator<(const edge &rhs)const{ return dist>rhs.dist;} }; edge e[maxn],edges[maxn<<1],*pt=edges,*head[nmax]; int fa[nmax],n,m,pre[nmax],son[nmax],size[nmax],dep[nmax],tp[nmax],id[nmax],idx[nmax],w[nmax],sum[nmax<<2]; void add(int u,int v,int d){ pt->to=v;pt->dist=d;pt->next=head[u];head[u]=pt++; pt->to=u;pt->dist=d;pt->next=head[v];head[v]=pt++; } int find(int x){ return fa[x]==x?x:fa[x]=find(fa[x]); } void dfs(int x){ size[x]=1; qwq(x) if(o->to!=pre[x]){ int to=o->to;pre[to]=x;dep[to]=dep[x]+1;w[to]=o->dist; dfs(to);size[x]+=size[to]; if(!son[x]||size[to]>size[son[x]]) son[x]=to; } } void DFS(int x,int top){ id[++id[0]]=x;idx[x]=id[0];tp[x]=top; if(son[x]) DFS(son[x],top); qwq(x) if(!idx[o->to]) DFS(o->to,o->to); } void build(int x,int l,int r){ if(l==r) { sum[x]=w[id[l]];return ; } int m=(l+r)>>1;build(lson);build(rson);sum[x]=min(sum[x<<1],sum[x<<1|1]); } int query(int tl,int tr,int x,int l,int r){ if(tl<=l&&tr>=r) return sum[x]; int m=(l+r)>>1;int ans=inf; if(tl<=m) ans=min(ans,query(tl,tr,lson)); if(tr>m) ans=min(ans,query(tl,tr,rson)); return ans; } int qmax(int a,int b){ if(find(a)!=find(b)) return -1; int ans=inf; while(tp[a]!=tp[b]){ if(dep[tp[a]]>dep[tp[b]]) swap(a,b); ans=min(ans,query(idx[tp[b]],idx[b],1,1,n)); b=pre[tp[b]]; } if(dep[a]>dep[b]) swap(a,b); if(idx[a]==idx[b]) return ans; ans=min(ans,query(idx[a]+1,idx[b],1,1,n)); return ans; } int main(){ n=read(),m=read(); rep(i,1,m) { edge &o=e[i]; o.from=read(),o.to=read(),o.dist=read(); } sort(e+1,e+m+1); rep(i,1,n) fa[i]=i; rep(i,1,m){ edge &o=e[i]; int ta=find(o.from),tb=find(o.to); if(ta!=tb){ add(o.from,o.to,o.dist); fa[ta]=tb; } } clr(son,0);clr(idx,0);id[0]=0; rep(i,1,n) if(!pre[i]) dep[i]=0,dfs(i); rep(i,1,n) if(!idx[i]) DFS(i,i); build(1,1,n); int Q=read(),u,v; rep(i,1,Q){ u=read(),v=read(); printf("%d ",qmax(u,v)); } }
bzoj1650:
二分答案+贪心判断。和noip2015day2t1差不多。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=50005; int a[nmax],N,M,L; bool check(int x){ int ans=0,pre=0; rep(i,1,N) { if(a[i]-a[pre]<x) ans++; else pre=i; } if(ans<=M) return true; return false; } int main(){ L=read(),N=read(),M=read(); rep(i,1,N) a[i]=read(); sort(a+1,a+N+1); int l=0,r=L,mid,ans=0; while(l<=r){ mid=(l+r)>>1; if(check(mid)) ans=mid,l=mid+1; else r=mid-1; } printf("%d ",ans); return 0; }
bzoj1648:
边数点数少直接暴力dfs
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define clr(x,c) memset(x,c,sizeof(x)) #define qwq(x) for(edge *o=head[x];o;o=o->next) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=1005; const int maxn=10005; const int inf=0x7f7f7f7f; struct edge{ int to;edge *next; }; edge edges[maxn],*pt=edges,*head[nmax]; int a[nmax],ans[nmax]; bool vis[nmax]; void add(int u,int v){ pt->to=v;pt->next=head[u];head[u]=pt++; } void dfs(int x){ vis[x]=true;ans[x]++; qwq(x) if(!vis[o->to]) dfs(o->to); } int main(){ int K=read(),N=read(),M=read(),u,v; rep(i,1,K) a[i]=read(); rep(i,1,M) u=read(),v=read(),add(u,v); rep(i,1,K) clr(vis,false),dfs(a[i]); int res=0; rep(i,1,N) if(ans[i]==K) res++; printf("%d ",res); return 0; }
bzoj1646:
简单bfs;
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define clr(x,c) memset(x,c,sizeof(x)) const int nmax=200005; int q[nmax],dist[nmax]; bool vis[nmax]; int main(){ int n,k; scanf("%d%d",&n,&k); int l=1,r=1; clr(vis,false);vis[n]=true; dist[n]=0; q[r]=n; while(l<=r){ int x=q[l];l++; if(x==k){ printf("%d ",dist[x]);return 0; } if(x-1>=0&&!vis[x-1]) q[++r]=x-1,vis[x-1]=true,dist[x-1]=dist[x]+1; if(x+1<=200000&&!vis[x+1]) q[++r]=x+1,vis[x+1]=true,dist[x+1]=dist[x]+1; if(x+x<=200000&&!vis[x+x]) q[++r]=x+x,vis[x+x]=true,dist[x+x]=dist[x]+1; } return 0; }
bzoj1644:
bfs。不知道为什么我这样子写WA了。。。放一下代码求指点。。挖坑有空再写。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define clr(x,c) memset(x,c,sizeof(x)) char s[105]; bool map[105][105]; int f[105][105],from[105][105]; queue<int>q,Q; int xx[5]={0,0,0,1,-1}; int yy[5]={0,1,-1,0,0}; int main(){ int n,sa,sb,ta,tb;scanf("%d",&n); rep(i,1,n){ scanf("%s",s+1); rep(j,1,n) { map[i][j]=s[j]=='x'?0:1; if(s[j]=='A') sa=i,sb=j; else if(s[j]=='B') ta=i,tb=j; } } clr(f,0x7f); f[sa][sb]=0; q.push(sa);Q.push(sb); int x,y,tx,ty; while(!q.empty()){ x=q.front(),y=Q.front();q.pop();Q.pop(); rep(i,1,4){ tx=x+xx[i],ty=y+yy[i]; if(tx<=0||ty<=0||tx>n||ty>n||!map[tx][ty]) continue; if(from[x][y]==i||x==sa&&y==sb) { if(f[x][y]<f[tx][ty]) q.push(tx),Q.push(ty),f[tx][ty]=f[x][y],from[tx][ty]=i; } else if(f[x][y]<f[tx][ty]-1) q.push(tx),Q.push(ty),f[tx][ty]=f[x][y]+1,from[tx][ty]=i; } } printf("%d ",f[ta][tb]); return 0; } /* 5 ..Bx. .xxA. ...x. .x... ..x..*/
bzoj1643:
O(n^3)暴力,然后第四个数可以推出来。。因为写过一道搜索+剪枝有一个剪枝类似这样子所以会。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define clr(x,c) memset(x,c,sizeof(x)) int a[105]; int main(){ int n,u,temp,orz,ans=0; scanf("%d",&n); int tmp=(int)sqrt(n)+1; rep(i,0,tmp) a[i]=i*i; rep(i,0,tmp) { rep(j,0,tmp) if(a[i]+a[j]<=n){ rep(k,0,tmp) if((u=a[i]+a[j]+a[k])<=n){ temp=n-u,orz=sqrt(temp); if(orz*orz==temp) ans++; } } } printf("%d ",ans); return 0; }
bzoj1641:
floyed即可。。。然而一看到题目就二话不说二分答案+暴力dfs(总是觉得应该可以卡时过去。然而还是tle了。。、不过这种做法应该是对的吧
/*#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define qwq(x) for(edge *o=head[x];o;o=o->next) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=305; const int maxn=25005; const int inf=0x7f7f7f7f; struct edge{ int to,dist;edge *next; bool flag; }; edge edges[maxn],*pt=edges,*head[nmax]; int N,M,Q; bool vis[nmax]; void add(int u,int v,int d){ pt->to=v;pt->dist=d;pt->next=head[u];head[u]=pt++; } bool dfs(int x,int t){ vis[x]=true; if(x==t) return true; qwq(x) if(!vis[o->to]&&o->flag){ if(dfs(o->to,t)) return true; } return false; } bool check(int x,int s,int t){ rep(i,1,N) qwq(i) if(o->dist<=x) o->flag=true;else o->flag=false; clr(vis,false); if(dfs(s,t)) return true; return false; } int main(){ N=read(),M=read(),Q=read(); int u,v,d,sum=0; rep(i,1,M) u=read(),v=read(),d=read(),add(u,v,d),sum=max(sum,d); rep(i,1,Q) { u=read(),v=read(); int l=0,r=sum,ans=-1,mid; while(l<=r){ mid=(l+r)>>1; if(check(mid,u,v)) ans=mid,r=mid-1; else l=mid+1; } printf("%d ",ans); } }*/ #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=305; const int maxn=25005; const int inf=0x7f7f7f7f; int dist[nmax][nmax]; int main(){ int N=read(),M=read(),Q=read(),u,v,d; clr(dist,0x7f); rep(i,1,M) u=read(),v=read(),d=read(),dist[u][v]=d; rep(k,1,N) rep(i,1,N) rep(j,1,N) if(dist[i][k]!=inf&&dist[k][j]!=inf) dist[i][j]=min(dist[i][j],max(dist[i][k],dist[k][j])); rep(i,1,Q) { u=read(),v=read(); if(dist[u][v]==inf) printf("-1 "); else printf("%d ",dist[u][v]); } return 0; }
bzoj1640:
直接模拟。。。然而没有看清题意WA了唉。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) const int nmax=2005; int a[nmax],ans[nmax]; char c[5]; int main(){ int n;scanf("%d",&n); rep(i,1,n){ scanf("%s",c); a[i]=c[0]-'A'; } int l=1,r=n,tmp; rep(k,1,n){ if(a[l]<a[r]) ans[k]=a[l],l++; else if(a[l]>a[r]) ans[k]=a[r],r--; else{ for(int i=l,j=r;i<=j;i++,j--){ if(a[i]<a[j]){ tmp=l;break; }else if(a[i]>a[j]){ tmp=r;break; }else if(i==j){ tmp=l;break; } } ans[k]=a[tmp]; tmp==l?l++:r--; } } rep(i,1,n){ putchar('A'+ans[i]); if(i%80==0) putchar(' '); } return 0; } /* 10 A C D E F B E D C B */
bzoj1639:
二分答案+贪心判断。这种模拟总有感觉自己会写WA,怀疑自己写错。但是只要用模拟一下数据的运算过程还是很容易判断写法的对错的。这也是模拟的调法吧。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=100005; const int inf=0x7f7f7f7f; int N,M,a[nmax]; bool check(int x){ int ans=0,cur=1,tmp; while(1){ tmp=a[cur]; if(tmp>x) return false; while(tmp<=x&&cur<=N) cur++,tmp+=a[cur]; ans++; if(cur>N) break; } if(ans<=M) return true; return false; } int main(){ N=read(),M=read(); rep(i,1,N) a[i]=read(); int l=0,r=inf,mid,ans=0; while(l<=r){ mid=(l+r)>>1; if(check(mid)) ans=mid,r=mid-1; else l=mid+1; } printf("%d ",ans); return 0; }
bzoj1638:
dfs。不会做,orz了hzwer(我原本的做法求方案数又是抱着应该可以卡过去的想法暴力dfs。。。stopstopstop小搜怡情爆搜伤身啊。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define qwq(x) for(edge *o=head[x];o;o=o->next) #define qaq(x) for(edge *o=h[x];o;o=o->next) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=5005; const int maxn=50005; const int inf=0x7f7f7f7f; bool in[nmax]; int s[maxn],t[maxn]; int f[nmax],dp[nmax]; struct edge{ int to;edge *next; }; edge edges[maxn],*pt=edges,*head[nmax]; edge e[maxn],*p=e,*h[nmax]; void add(int u,int v){ pt->to=v;pt->next=head[u];head[u]=pt++; } void adde(int u,int v){ p->to=v;p->next=h[u];h[u]=p++; } void dfs(int x){ if(!head[x]) { dp[x]=1;return ; } qwq(x){ if(!dp[o->to]) dfs(o->to); dp[x]+=dp[o->to]; } } void DFS(int x){ if(!h[x]) { f[x]=1;return ; } qaq(x){ if(!f[o->to]) DFS(o->to); f[x]+=f[o->to]; } } int main(){ int N=read(),M=read(),u,v; rep(i,1,M) u=read(),v=read(),add(u,v),adde(v,u),in[v]=true,s[i]=u,t[i]=v; rep(i,1,N) if(!in[i]) dfs(i); DFS(N); int ans=0; rep(i,1,M) ans=max(ans,dp[t[i]]*f[s[i]]); printf("%d ",ans); return 0; }
bzoj1637:
1就+1,0就-1,然后找乱搞就可以了。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=50005; struct node{ int cur,x; bool operator<(const node&rhs)const{ return cur<rhs.cur;} }; node nodes[nmax]; int sum[nmax],ll[nmax+nmax],rr[nmax+nmax]; int main(){ int n=read(); rep(i,1,n) nodes[i].x=read(),nodes[i].cur=read(); sort(nodes+1,nodes+n+1); rep(i,1,n) { node&o=nodes[i]; if(o.x) sum[i]=sum[i-1]+1; else sum[i]=sum[i-1]-1; if(!ll[sum[i]+n]) ll[sum[i]+n]=i; else rr[sum[i]+n]=i; } int ans=0; rep(i,0,n+n){ if(!rr[i]) continue; ans=max(ans,nodes[rr[i]].cur-nodes[ll[i]+1].cur); } printf("%d ",ans); return 0; }
bzoj1636:
多次求区间最大最小差值。ST和线段树都可以搞。没写过ST写一下还是挺好写的。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } char s[100]; void print(int x){ int cur=0; if(!x) { putchar('0');putchar(' '); return; } while(x){ s[++cur]=x%10+'0',x/=10; } dwn(i,cur,1) putchar(s[i]); putchar(' '); } const int nmax=50005; int a[nmax],f[nmax][20],g[nmax][20]; int main(){ int N=read(),Q=read(),u,v; rep(i,1,N) a[i]=read(),f[i][0]=g[i][0]=a[i]; for(int k=1;(1<<k)<=N;k++) for(int i=1;i+(1<<k)-1<=N;i++) f[i][k]=max(f[i][k-1],f[i+(1<<k-1)][k-1]),g[i][k]=min(g[i][k-1],g[i+(1<<k-1)][k-1]); rep(i,1,Q){ u=read(),v=read(); int tmp; for(tmp=0;(1<<tmp)<=v-u+1;tmp++);tmp--; print(max(f[u][tmp],f[v-(1<<tmp)+1][tmp])-min(g[u][tmp],g[v-(1<<tmp)+1][tmp])); } return 0; }
bzoj1635:
差分序列!!!感觉好高大上的东西。就是可以区间内加减一个数。然后就可以啦。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=10005; int ans[nmax]; struct node{ int x,y; bool operator<(const node&rhs)const{ return x<rhs.x||x==rhs.x&&y<rhs.y;} }; node nodes[nmax]; int main(){ int N=read(),I=read(),H=read(),M=read(),u,v; rep(i,1,M) { node&o=nodes[i]; o.x=read(),o.y=read(); if(o.x>o.y) swap(o.x,o.y); } sort(nodes+1,nodes+M+1); rep(i,1,M){ if(nodes[i].x==nodes[i-1].x&&nodes[i].y==nodes[i-1].y) continue; ans[nodes[i].x+1]--;ans[nodes[i].y]++; } rep(i,1,N) printf("%d ",(ans[i]+=ans[i-1])+H);printf(" "); return 0; }
bzoj1634:
贪心。对于AB判断A前B后或者A后B前哪一种更优可以推出表达式。那么久可以确定顺序了。以点破面?。。。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define clr(x,c) memset(x,c,sizeof(x)) #define ll long long const int nmax=100005; struct node{ int w,t,num; bool operator<(const node&rhs)const{ return rhs.w*t>w*rhs.t;} }; node nodes[nmax]; int main(){ int N;scanf("%d",&N); rep(i,1,N) scanf("%d%d",&nodes[i].w,&nodes[i].t),nodes[i].num=i; sort(nodes+1,nodes+N+1); ll sum=0,ans=0; rep(i,1,N) ans+=sum*nodes[i].t<<1,sum+=nodes[i].w; printf("%lld ",ans); return 0; }
bzoj1632:
bfs。多加一维来乱搞(然而我一直调不出来。。。挖坑。啊我为什么bfs总是WA啊。。。
bzoj1631:
两遍spfa就可以了。。。将边反过来存储就又变成单源最短路了。。以前见过。。
#include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define clr(x,c) memset(x,c,sizeof(x)) #define qwq(x) for(edge *o=head[x];o;o=o->next) #define qaq(x) for(edge *o=h[x];o;o=o->next) int read(){ int x=0;char c=getchar();int f=1; while(!isdigit(c)){ if(c=='-') f=-1;c=getchar(); } while(isdigit(c)) x=x*10+c-'0',c=getchar(); return f*x; } const int nmax=1005; const int maxn=100005; const int inf=0x7f7f7f7f; struct edge{ int to,dist;edge*next; }; edge edges[maxn],*pt=edges,*head[nmax]; edge e[maxn],*p=e,*h[nmax]; void add(int u,int v,int d){ pt->to=v;pt->dist=d;pt->next=head[u];head[u]=pt++; } void adde(int u,int v,int d){ p->to=v;p->dist=d;p->next=h[u];h[u]=p++; } queue<int>q; int dist[nmax],dis[nmax]; bool inq[nmax]; void spfa(int t){ clr(inq,false);inq[t]=1; clr(dist,0x7f);dist[t]=0; q.push(t); while(!q.empty()){ int x=q.front();q.pop();inq[x]=false; qwq(x) if(dist[o->to]>dist[x]+o->dist){ dist[o->to]=dist[x]+o->dist; if(!inq[o->to]) q.push(o->to),inq[o->to]=true; } } } void SPFA(int t){ clr(inq,false);inq[t]=1; clr(dis,0x7f);dis[t]=0; q.push(t); while(!q.empty()){ int x=q.front();q.pop();inq[x]=false; qaq(x) if(dis[o->to]>dis[x]+o->dist){ dis[o->to]=dis[x]+o->dist; if(!inq[o->to]) q.push(o->to),inq[o->to]=true; } } } int main(){ int N=read(),M=read(),T=read(),u,v,d; rep(i,1,M){ u=read(),v=read(),d=read(); add(u,v,d);adde(v,u,d); } spfa(T);SPFA(T); int ans=-1; rep(i,1,N) ans=max(ans,dist[i]+dis[i]); printf("%d ",ans); return 0; }
bzoj1630:
这可是道背包dp神题啊。挖坑似乎可以前缀和优化+滚动数组。。。然而我只会滚动数组。(防止mle。好劲啊这是。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=1e5+5; const int maxn=1e3+5; const int mod=1e6; int dp[nmax],cnt[maxn]; int main(){ int T=read(),A=read(),S=read(),B=read(),u; rep(i,1,A) u=read(),cnt[u]++; dp[0]=1; rep(i,1,T) dwn(j,B,1) rep(k,1,cnt[i]) { if(j<k) break; dp[j]=(dp[j]+dp[j-k])%mod; } int ans=0; rep(i,S,B) ans=(ans+dp[i])%mod; printf("%d ",ans); return 0; }
bzoj1629:
贪心。。AB谁前谁后可以判断。和1634是同一种类型题。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=50005; const int inf=0x7f7f7f7f; struct node{ int w,t; bool operator<(const node&rhs)const{ return max(-t,w-rhs.t)<max(-rhs.t,rhs.w-t);} }; node nodes[nmax]; int main(){ int n=read(); rep(i,1,n) nodes[i].w=read(),nodes[i].t=read(); sort(nodes+1,nodes+n+1); int ans=-inf,sum=0; rep(i,1,n) ans=max(ans,sum-nodes[i].t),sum+=nodes[i].w; printf("%d ",ans); return 0; }
bzoj1628:
单调栈!边界没有处理好!!!注意边界。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=50005; int a[nmax],s[nmax]; int main(){ int N=read(),W=read(),u,v; rep(i,1,N) u=read(),a[i]=read(); int r=0,ans=0; rep(i,1,N){ while(r&&s[r]>a[i]) r--; if(s[r]!=a[i]) ans++; s[++r]=a[i]; } printf("%d ",ans); return 0; }
bzoj1627:
简单bfs。。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar();int f=1; while(!isdigit(c)){ if(c=='-') f=-1;c=getchar(); } while(isdigit(c)) x=x*10+c-'0',c=getchar(); return f*x; } const int nmax=1005; const int orz=500; bool on[nmax][nmax],vis[nmax][nmax]; int dist[nmax][nmax]; struct node{ int x,y; node(int x,int y):x(x),y(y){} }; queue<node>q; int xx[5]={0,0,0,1,-1}; int yy[5]={0,1,-1,0,0}; int main(){ int ta=read(),tb=read(),N=read(),u,v,d; ta+=orz,tb+=orz; clr(vis,false);clr(on,true); rep(i,1,N) u=read(),v=read(),on[u+orz][v+orz]=false; q.push(node(orz,orz));vis[orz][orz]=true; while(!q.empty()){ node t=q.front();q.pop(); rep(i,1,4){ int tx=t.x+xx[i],ty=t.y+yy[i]; if(tx&&ty&&tx<=1000&&ty<=1000&&!vis[tx][ty]&&on[tx][ty]) { vis[tx][ty]=true;dist[tx][ty]=dist[t.x][t.y]+1; q.push(node(tx,ty)); if(tx==ta&&ty==tb){ printf("%d ",dist[tx][ty]); return 0; } } } } return 0; }
bzoj1626:
最小生成树。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=1005; const int maxn=1000005; int fa[nmax],xi[nmax],yi[nmax]; struct edge{ int from,to;double dist; bool operator<(const edge&rhs)const{ return dist<rhs.dist;} }; edge edges[maxn]; int find(int x){ return fa[x]==x?x:fa[x]=find(fa[x]); } int main(){ int N=read(),M=read(),u,v,ta,tb; rep(i,1,N) xi[i]=read(),yi[i]=read(); rep(i,1,N) fa[i]=i; rep(i,1,M){ u=read(),v=read(); ta=find(u),tb=find(v); if(ta!=tb) fa[ta]=tb; } int cnt=0; rep(i,1,N-1) rep(j,i+1,N) { edge &o=edges[++cnt]; o.from=i,o.to=j; o.dist=sqrt((double)(xi[i]-xi[j])*(xi[i]-xi[j])+(double)(yi[i]-yi[j])*(yi[i]-yi[j])); } sort(edges+1,edges+cnt+1); //rep(i,1,cnt) printf("%d %d %lf ",edges[i].from,edges[i].to,edges[i].dist); double ans=0;int res=M; rep(i,1,cnt){ ta=find(edges[i].from);tb=find(edges[i].to); if(ta!=tb) fa[ta]=tb,ans+=edges[i].dist,res++; if(res==N-1) break; } printf("%.2lf ",ans); return 0; }
bzoj1625:
背包dp。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=3500; const int maxn=13000; int w[nmax],c[nmax]; int dp[maxn]; int main(){ int N=read(),M=read(); rep(i,1,N) w[i]=read(),c[i]=read(); rep(i,1,N) dwn(j,M,w[i]) dp[j]=max(dp[j],dp[j-w[i]]+c[i]); printf("%d ",dp[M]); return 0; }
bzoj1624:
floyed。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=105; const int maxn=10005; int dist[nmax][nmax]; int ans[maxn]; int main(){ int N=read(),M=read(); rep(i,1,M) ans[i]=read(); rep(i,1,N) rep(j,1,N) dist[i][j]=read(); rep(k,1,N) rep(i,1,N) rep(j,1,N) dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]); int res=0; rep(i,1,M-1) res+=dist[ans[i]][ans[i+1]]; printf("%d ",res); return 0; }
bzoj1623:
贪心。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=50005; int a[nmax]; int main(){ int N=read(),M=read(),D=read(),L=read(); rep(i,1,N) a[i]=read(); sort(a+1,a+N+1); int ans=0; rep(i,1,N){ if(a[i]-ans/M*D>=L) ans++; } printf("%d ",ans); return 0; }
bzoj1622:
乱搞。。(这种模拟题我总是很虚啊。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define clr(x,c) memset(x,c,sizeof(x)) const int nmax=1005; const int maxn=105; char s[nmax][nmax],t[maxn][35]; int ans[nmax]; int lena[nmax],lenb[nmax]; int main(){ int N,M; scanf("%d%d",&N,&M); rep(i,1,N) { scanf("%s",s[i]); lena[i]=strlen(s[i]); rep(j,0,lena[i]-1) if(s[i][j]<'a') s[i][j]+=32; } rep(i,1,M) { scanf("%s",t[i]); lenb[i]=strlen(t[i]); rep(j,0,lenb[i]-1) if(t[i][j]<'a') t[i][j]+=32; } rep(i,1,N) rep(j,1,M) { int p=0,pt=0; while(p<lena[i]&&pt<lenb[j]){ if(s[i][p]==t[j][pt]) pt++; p++; } if(pt==lenb[j]) ans[i]++; } rep(i,1,N) printf("%d ",ans[i]); return 0; }
bzoj1621:
递归。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } int n,K; int dfs(int x){ if((x+K)%2) return 1; if(x<=K) return 1; return dfs((x+K)/2)+dfs((x-K)/2); } int main(){ n=read(),K=read(); printf("%d ",dfs(n)); return 0; }
bzoj1620:
二分答案+贪心判断。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=100005; const int inf=0x7f7f7f7f; int N,M,a[nmax]; bool check(int x){ int ans=0,cur=1,tmp; while(1){ tmp=a[cur]; if(tmp>x) return false; while(tmp<=x&&cur<=N) cur++,tmp+=a[cur]; ans++; if(cur>N) break; } if(ans<=M) return true; return false; } int main(){ N=read(),M=read(); rep(i,1,N) a[i]=read(); int l=0,r=inf,mid,ans=0; while(l<=r){ mid=(l+r)>>1; if(check(mid)) ans=mid,r=mid-1; else l=mid+1; } printf("%d ",ans); return 0; }
bzoj1618:
背包dp。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=60005; const int maxn=105; const int inf=0x7f7f7f7f; int w[maxn],c[maxn]; int f[nmax]; int main(){ int n=read(),h=read(); rep(i,1,n) w[i]=read(),c[i]=read(); clr(f,0x7f);f[0]=0; rep(i,1,n) rep(j,0,h) if(f[j]!=inf) f[j+w[i]]=min(f[j+w[i]],f[j]+c[i]); int ans=inf; rep(i,h,h+5005) ans=min(ans,f[i]); printf("%d ",ans); return 0; }
bzoj1617:
区间dp。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int x; int read(){ x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=2505; const int inf=0x7f7f7f7f; int cost[nmax],dp[nmax]; int main(){ int n=read(),m=read(); rep(i,1,n) cost[i]=read(),cost[i]+=cost[i-1]; clr(dp,0x7f);dp[0]=0; rep(i,1,n) rep(j,0,i-1) dp[i]=min(dp[i],dp[j]+cost[i-j]+m+m); printf("%d ",dp[n]-m); return 0; }
bzoj1616:
多加一维然后dp转移即可。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=105; const int maxn=20; int dp[maxn][nmax][nmax],a[nmax][nmax]; char s[nmax]; int xx[5]={0,0,0,1,-1}; int yy[5]={0,1,-1,0,0}; int main(){ int n=read(),m=read(),T=read(); rep(i,1,n){ scanf("%s",s); rep(j,1,m) a[i][j]=s[j-1]=='.'?1:0; } int sa=read(),ta=read(),sb=read(),tb=read(); dp[0][sa][ta]=1; rep(i,1,T) rep(j,1,n) rep(k,1,m) { if(a[j][k]) { rep(o,1,4){ int tx=j+xx[o],ty=k+yy[o]; if(tx&&ty&&tx<=n&&ty<=m&&a[tx][ty]) dp[i][j][k]+=dp[i-1][tx][ty]; } }else dp[i][j][k]=0; } printf("%d ",dp[T][sb][tb]); return 0; }
bzoj1615:
乱搞。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar();int f=1; while(!isdigit(c)){ if(c=='-') f=-1;c=getchar(); } while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x*f; } const int nmax=205; int x[nmax],y[nmax]; double ans[nmax]; int main(){ int n=read(); rep(i,1,n) x[i]=read(),y[i]=read(); int cnt=0;bool f=false; rep(i,1,n) rep(j,1,n) if(i!=j){ if(x[i]==x[j]) f=true; else ans[++cnt]=(double)(y[i]-y[j])/(x[i]-x[j]); } sort(ans+1,ans+cnt+1); int res=0; if(cnt) res++; rep(i,2,cnt) if(ans[i]!=ans[i-1]) res++; if(f) res++; printf("%d ",res); return 0; }
bzoj1612:
spfa求路径最小值。。。都是差不多的啦。
#include<cstdio> #include<iostream> #include<cstring> #include<queue> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define clr(x,c) memset(x,c,sizeof(x)) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define qwq(x) for(edge *o=head[x];o;o=o->next) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=1005; const int maxn=10005; const int inf=0x7f7f7f7f; struct edge{ int to,dist;edge *next; }; edge edges[maxn],*pt=edges,*head[nmax]; void add(int u,int v,int d){ pt->to=v;pt->dist=d;pt->next=head[u];head[u]=pt++; pt->to=u;pt->dist=d;pt->next=head[v];head[v]=pt++; } struct node{ int x,k; node(int x,int k):x(x),k(k){} }; queue<node>q; int dist[nmax][nmax]; bool inq[nmax][nmax]; void spfa(int K,int n){ clr(dist,0x7f);dist[1][0]=0; clr(inq,false);inq[1][0]=true; q.push(node(1,0)); while(!q.empty()){ node oo=q.front();q.pop();inq[oo.x][oo.k]=false; qwq(oo.x){ int to=o->to; if(dist[to][oo.k]>max(dist[oo.x][oo.k],o->dist)) { dist[to][oo.k]=max(dist[oo.x][oo.k],o->dist); if(!inq[to][oo.k]){ q.push(node(to,oo.k));inq[to][oo.k]=true; } } if(oo.k>=K) continue; if(dist[to][oo.k+1]>dist[oo.x][oo.k]){ dist[to][oo.k+1]=dist[oo.x][oo.k]; if(!inq[to][oo.k+1]){ q.push(node(to,oo.k+1));inq[to][oo.k+1]=true; } } } } if(dist[n][K]==inf) printf("-1 "); else printf("%d ",dist[n][K]); return ; } int main(){ int n=read(),m=read(),p=read(),u,v,d; rep(i,1,m) u=read(),v=read(),d=read(),add(u,v,d); spfa(p,n); return 0; }
bzoj1612:
暴力dfsQAQ。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define clr(x,c) memset(x,c,sizeof(x)) #define qwq(x) for(edge *o=head[x];o;o=o->next) #define qaq(x) for(edge *o=h[x];o;o=o->next) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=105; const int maxn=4505; const int inf=0x7f7f7f7f; struct edge{ int to;edge *next; }; edge edges[maxn],*pt=edges,*head[nmax]; edge e[maxn],*p=e,*h[nmax]; int ans[nmax]; bool vis[nmax]; void add(int u,int v){ pt->to=v;pt->next=head[u];head[u]=pt++; p->to=u;p->next=h[v];h[v]=p++; } void dfs(int x){ qwq(x) if(!vis[o->to]) ans[o->to]++,vis[o->to]=true,dfs(o->to); } void DFS(int x){ qaq(x) if(!vis[o->to]) ans[o->to]++,vis[o->to]=true,DFS(o->to); } int main(){ int n=read(),m=read(),u,v; rep(i,1,m) u=read(),v=read(),add(u,v); rep(i,1,n) { clr(vis,false);dfs(i); } rep(i,1,n){ clr(vis,false);DFS(i); } int res=0; rep(i,1,n) if(ans[i]==n-1) res++; printf("%d ",res); return 0; }
bzoj1611:
对于每个点,能转移到该点必定没有被炸,那么可以利用这一点性质在bfs时转移!。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=305; const int inf=0x7f7f7f7f; int map[nmax][nmax],dist[nmax][nmax]; bool vis[nmax][nmax]; struct node{ int x,y; node(int x,int y):x(x),y(y){} }; queue<node>q; int xx[5]={0,0,0,1,-1}; int yy[5]={0,1,-1,0,0}; int main(){ int m=read(),u,v,d; clr(map,0x7f); rep(i,1,m) { u=read(),v=read(),d=read();map[u][v]=min(map[u][v],d); rep(k,1,4) if(u+xx[k]>=0&&v+yy[k]>=0) map[u+xx[k]][v+yy[k]]=min(d,map[u+xx[k]][v+yy[k]]); } if(map[0][0]==inf){ printf("0 ");return 0; } q.push(node(0,0)); clr(vis,false);vis[0][0]=true;dist[0][0]=0; while(!q.empty()){ node o=q.front();q.pop(); rep(i,1,4){ int x=o.x,y=o.y,tx=x+xx[i],ty=y+yy[i]; if(tx<0||ty<0||map[tx][ty]-1<=dist[x][y]||vis[tx][ty]) continue; if(map[tx][ty]==inf){ printf("%d ",dist[x][y]+1);return 0; } q.push(node(tx,ty));dist[tx][ty]=dist[x][y]+1;vis[tx][ty]=true; } } printf("-1 "); return 0; }
bzoj4395:
暴力+bfs。多次bfs就可以了。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=105; const int maxn=20005; const int inf=0x7f7f7f7f; struct edge{ int to,too;edge *next; }; edge edges[maxn],*pt=edges,*head[nmax][nmax]; bool on[nmax][nmax],vis[nmax][nmax]; void add(int x,int y,int d,int w){ pt->to=d;pt->too=w;pt->next=head[x][y];head[x][y]=pt++; } struct node{ int a,b; node(int a,int b):a(a),b(b){} }; queue<node>q; int xx[5]={0,0,0,1,-1}; int yy[5]={0,1,-1,0,0}; int main(){ int n=read(),m=read(); rep(i,1,m){ int u=read(),v=read(),d=read(),w=read(); add(u,v,d,w); } int ans=1,last=1;on[1][1]=true; while(1){ q.push(node(1,1)); clr(vis,0);vis[1][1]=true; while(!q.empty()){ node x=q.front();q.pop(); for(edge *o=head[x.a][x.b];o;o=o->next){ if(!on[o->to][o->too]) on[o->to][o->too]=true,ans++; } rep(i,1,4){ int tx=x.a+xx[i],ty=x.b+yy[i]; if(tx&&ty&&tx<=n&&ty<=n){ if(on[tx][ty]&&!vis[tx][ty]) vis[tx][ty]=true,q.push(node(tx,ty)); } } } if(last==ans) break; last=ans; } printf("%d ",ans); return 0; }
bzoj1318:
神题。。这种题都不知道怎么想出来的。。。orzhzwer后勉勉强强懂了。。。然而太神了这。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define ll long long int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=1000015; const int inf=0x7f7f7f7f; int n,ans=-1,last[nmax],next[nmax],a[nmax]; ll sum[nmax]; bool vis[nmax]; void solve(int x){ int len=0,rmax=inf; rep(i,x+1,n) { if(a[i]==1) break; if(!vis[a[i]]) vis[a[i]]=true; else { rmax=i;break; } } dwn(i,x,1){ if(a[i]==1&&i!=x) break; rmax=min(rmax,next[i]); len=max(len,a[i]); if(i+len-1<=n&&i+len-1<rmax&&sum[i+len-1]-sum[i-1]==(ll)len*(len+1)/2) ans=max(ans,len); } rep(i,x+1,n) { if(a[i]==1) break; vis[a[i]]=false; } } void work(){ clr(last,0x7f); dwn(i,n,1) { next[i]=last[a[i]]; last[a[i]]=i; } rep(i,1,n) if(a[i]==1) solve(i); } int main(){ n=read(); rep(i,1,n) a[i]=read(),sum[i]=sum[i-1]+a[i]; work(); reverse(a+1,a+n+1); clr(sum,0); rep(i,1,n) sum[i]=sum[i-1]+a[i]; work(); printf("%d ",ans); return 0; }
bzoj1306:
搜索+剪枝!。我写了三个剪枝但是tle了。到网上一看然后再加一个剪枝就卡过去了。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } int f[4]={3,1,0,0}; int ans[9],a[9],res=0,n; void dfs(int x,int y){ if(ans[x]>a[x]) return ; if(ans[x]+(n-y+1)*3<a[x]) return ; if(x==n) { res++;return ; } if(y==n){ int tmp=a[x]-ans[x]; if(tmp==2) return ; ans[y]+=f[tmp]; dfs(x+1,x+2); ans[y]-=f[tmp]; }else{ ans[x]+=3;dfs(x,y+1);ans[x]-=3; ans[x]++,ans[y]++,dfs(x,y+1),ans[x]--,ans[y]--; ans[y]+=3;dfs(x,y+1),ans[y]-=3; } } int main(){ n=read(); rep(i,1,n) a[i]=read(); dfs(1,2); printf("%d ",res); return 0; }
bzoj1303:
大于的就+1,小于的就-1,求中位数子串有多少个。。然后乱搞就可以了。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=200005; const int inf=0x7f7f7f7f; int a[nmax],cnt[nmax],sum[nmax];//qi ou int main(){ int n=read(),m=read(),cur,u; rep(i,1,n){ a[i]=read(); if(a[i]==m) cur=i; a[i]+=100000; } m+=100000; sum[100000]=1;a[0]=100000; rep(i,1,cur-1){ if(a[i]>m) a[i]=a[i-1]+1; else a[i]=a[i-1]-1; if(i%2) cnt[a[i]]++; else sum[a[i]]++; } int ans=0; rep(i,cur,n){ if(a[i]>m) a[i]=a[i-1]+1; else if(a[i]==m) a[i]=a[i-1]; else a[i]=a[i-1]-1; if(i%2) ans+=sum[a[i]]; else ans+=cnt[a[i]]; } printf("%d ",ans); return 0; }