noip2012~2015刷题小记录
2012d1t1 密码
模拟题
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 #include<queue> 9 #include<vector> 10 using namespace std; 11 12 const int N=1100; 13 char s[N],c[N],p[30][30]; 14 15 int myabs(int x){return x>0 ? x:-x;} 16 17 void init() 18 { 19 for(int i=0;i<26;i++) 20 { 21 int k=i; 22 for(int j=0;j<26;j++) 23 { 24 if(k==26) k=0; 25 p[i][j]=k; 26 k++; 27 } 28 } 29 } 30 31 char fd(char a,char b) 32 { 33 int tmp=0,x,y; 34 if(a>='a' && a<='z') x=a-'a'; 35 else x=a-'A'; 36 if(b>='a' && b<='z') tmp=1,y=b-'a'; 37 else y=b-'A'; 38 for(int i=0;i<26;i++) 39 { 40 if(p[x][i]==y) 41 { 42 if(tmp==0) return i+'A'; 43 return i+'a'; 44 } 45 } 46 } 47 48 int main() 49 { 50 freopen("a.in","r",stdin); 51 scanf("%s",s+1); 52 scanf("%s",c+1); 53 init(); 54 int sl=strlen(s+1); 55 int cl=strlen(c+1); 56 int j=1; 57 for(int i=1;i<=cl;i++) 58 { 59 if(j==sl+1) j=1; 60 printf("%c",fd(s[j],c[i])); 61 j++; 62 } 63 return 0; 64 }
2012d1t2 国王游戏
考虑相邻的两个交换。要打高精度。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 #include<queue> 9 #include<vector> 10 using namespace std; 11 12 const int N=11000; 13 int n; 14 struct nd{int a,b;}p[N]; 15 struct node{int sl,s[N];}; 16 17 bool cmp(nd x,nd y){return x.a*x.b < y.a*y.b;} 18 19 node maxx(node a,node b) 20 { 21 if(a.sl!=b.sl) return (a.sl>b.sl) ? a:b; 22 for(int i=a.sl;i>=1;i--) 23 { 24 if(a.s[i]!=b.s[i]) return (a.s[i]>b.s[i]) ? a:b; 25 } 26 return a; 27 } 28 29 node mult(node a,int b) 30 { 31 node c; 32 int x=b,sl=0; 33 while(x) {sl++;x/=10;} 34 c.sl=a.sl+sl; 35 memset(c.s,0,sizeof(c.s)); 36 for(int i=1;i<=c.sl;i++)//debug c.sl not a.sl 37 { 38 c.s[i]+=a.s[i]*b; 39 if(c.s[i]>=10) c.s[i+1]+=c.s[i]/10,c.s[i]%=10; 40 } 41 while(c.sl>1 && c.s[c.sl]==0) c.sl--; 42 while(c.s[c.sl]>=10) c.s[c.sl+1]+=c.s[c.sl]/10,c.s[c.sl]%=10,c.sl++; 43 return c; 44 } 45 46 node div(node a,int b) 47 { 48 node c; 49 c.sl=a.sl; 50 memset(c.s,0,sizeof(c.s)); 51 int now=0; 52 for(int i=a.sl;i>=1;i--) 53 { 54 now=now*10+a.s[i]; 55 if(now>=b) c.s[i]+=now/b,now=now%b; 56 } 57 for(int i=1;i<=c.sl;i++) 58 { 59 if(c.s[i]>=10) c.s[i+1]+=c.s[i]/10,c.s[i]%=10; 60 } 61 while(c.sl>1 && c.s[c.sl]==0) c.sl--; 62 return c; 63 } 64 65 int main() 66 { 67 freopen("a.in","r",stdin); 68 freopen("a.out","w",stdout); 69 scanf("%d",&n); 70 for(int i=1;i<=n+1;i++) 71 { 72 scanf("%d%d",&p[i].a,&p[i].b); 73 } 74 sort(p+2,p+2+n,cmp); 75 node t,ans;int x=p[1].a; 76 t.sl=0;ans.sl=1; 77 memset(ans.s,0,sizeof(ans.s)); 78 while(x) 79 { 80 t.s[++t.sl]=x%10; 81 x/=10; 82 } 83 int i; 84 for(i=2;i<=n+1;i++) 85 { 86 ans=maxx(ans,div(t,p[i].b)); 87 t=mult(t,p[i].a); 88 } 89 output(ans); 90 return 0; 91 }
2012d1t3 开车旅行
倍增。然后因为inf开得不够大wa了一发?
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 #include<queue> 9 #include<vector> 10 using namespace std; 11 12 typedef long long LL;////// 13 const LL N=110000,S=30,D=20,INF=(LL)1e15; 14 const double inf=(double)1e9; 15 LL n,m,h[N],nt1[N],nt2[N],f[N][S],fa[N][S],fb[N][S]; 16 17 struct cmp{ 18 bool operator()(const LL &x,const LL &y)const 19 { 20 if(h[x]!=h[y]) return h[x]<h[y]; 21 return x<y; 22 } 23 }; 24 set<LL,cmp> s; 25 26 LL myabs(LL x){return x>0 ? x:-x;} 27 28 void fd(LL x,LL len,LL &al,LL &bl) 29 { 30 al=0;bl=0; 31 for(LL i=D;i>=0;i--) 32 { 33 if(f[x][i] && al+fa[x][i]+bl+fb[x][i]<=len) al+=fa[x][i],bl+=fb[x][i],x=f[x][i]; 34 } 35 if(nt2[x] && al+bl+myabs(h[nt2[x]]-h[x])<=len) al+=myabs(h[nt2[x]]-h[x]); 36 return; 37 } 38 39 int main() 40 { 41 freopen("a.in","r",stdin); 42 // freopen("a.out","w",stdout); 43 scanf("%lld",&n); 44 s.clear(); 45 set<LL>::iterator it,itt; 46 h[0]=-INF;s.insert(0); 47 h[n+1]=INF;s.insert(n+1); 48 for(LL i=1;i<=n;i++) 49 { 50 scanf("%lld",&h[i]); 51 } 52 memset(nt1,0,sizeof(nt1)); 53 memset(nt2,0,sizeof(nt2)); 54 LL x,y; 55 for(LL i=n;i>=1;i--) 56 { 57 it=s.lower_bound(i);x=(*it); 58 itt=it;itt--;y=(*itt); 59 if(x==n+1 && y==0) 60 { 61 s.insert(i); 62 continue; 63 } 64 if(h[x]-h[i]<h[i]-h[y]) 65 { 66 nt1[i]=x; 67 it++;x=(*it); 68 } 69 else 70 { 71 nt1[i]=y; 72 itt--;y=(*itt); 73 } 74 s.insert(i); 75 if(x==n+1 && y==0) continue; 76 if(h[x]-h[i]<h[i]-h[y]) nt2[i]=x; 77 else nt2[i]=y; 78 } 79 memset(f,0,sizeof(f)); 80 for(LL i=1;i<=n;i++) 81 { 82 LL x=nt2[i],y=nt1[x]; 83 if(x && y) 84 { 85 f[i][0]=y; 86 fa[i][0]=myabs(h[x]-h[i]); 87 fb[i][0]=myabs(h[y]-h[x]); 88 } 89 } 90 for(LL j=1;j<=D;j++) 91 for(LL i=1;i<=n;i++) 92 { 93 f[i][j]=f[f[i][j-1]][j-1]; 94 if(f[i][j]) fa[i][j]=fa[i][j-1]+fa[f[i][j-1]][j-1]; 95 if(f[i][j]) fb[i][j]=fb[i][j-1]+fb[f[i][j-1]][j-1]; 96 } 97 LL al,bl,len,st,id; 98 double ans=inf+100,now; 99 scanf("%lld",&len); 100 for(LL i=1;i<=n;i++) 101 { 102 fd(i,len,al,bl); 103 if(bl==0) now=inf; 104 else now=(double)al/(double)bl; 105 if(now<ans) ans=now,id=i; 106 else if(now==ans && h[i]>h[id]) id=i; 107 } 108 printf("%lld\n",id); 109 scanf("%lld",&m); 110 for(LL i=1;i<=m;i++) 111 { 112 scanf("%lld%lld",&st,&len); 113 fd(st,len,al,bl); 114 printf("%lld %lld\n",al,bl); 115 } 116 return 0; 117 }
2012d2t1 同余方程
exgcd裸题。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 #include<queue> 9 #include<vector> 10 using namespace std; 11 12 void exgcd(int a,int b,int &x,int &y) 13 { 14 if(b==0) {x=1;y=0;return ;} 15 int tx,ty; 16 exgcd(b,a%b,tx,ty); 17 x=ty;y=tx-(a/b)*ty; 18 return; 19 } 20 21 int main() 22 { 23 freopen("a.in","r",stdin); 24 int a,b,x,y; 25 scanf("%d%d",&a,&b); 26 exgcd(a,b,x,y); 27 x=(x%b+b)%b; 28 printf("%d\n",x); 29 return 0; 30 }
2012d2t2 借教室
原本想用线段树的。。后来发现(被大神告诉说)二分就可以了。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 #include<queue> 9 #include<vector> 10 using namespace std; 11 12 typedef long long LL; 13 const LL N=1100000; 14 LL n,m,a[N],b[N]; 15 struct node{ 16 LL l,r,d; 17 }q[N]; 18 19 bool check(LL x) 20 { 21 memset(b,0,sizeof(b)); 22 for(LL i=1;i<=x;i++) 23 { 24 b[q[i].l]+=q[i].d; 25 b[q[i].r+1]-=q[i].d; 26 } 27 LL now=0; 28 for(LL i=1;i<=n;i++) 29 { 30 now+=b[i]; 31 if(a[i]-now<0) return 0; 32 } 33 return 1; 34 } 35 36 int main() 37 { 38 freopen("a.in","r",stdin); 39 scanf("%lld%lld",&n,&m); 40 for(LL i=1;i<=n;i++) scanf("%lld",&a[i]); 41 for(LL i=1;i<=m;i++) scanf("%lld%lld%lld",&q[i].d,&q[i].l,&q[i].r); 42 if(check(m)) printf("0\n"); 43 else 44 { 45 LL l=1,r=m,mid; 46 while(l<r) 47 { 48 mid=(l+r)/2; 49 if(check(mid)) l=mid+1; 50 else r=mid; 51 } 52 printf("-1\n%lld\n",l); 53 } 54 return 0; 55 }
2012d2t3 疫情控制
难得自己推出来。。当然是在大神告诉我坑点的情况下。
二分+贪心。
坑点:一个军队如果先把它放到根节点上,然后它可能会回不到原来那棵子树。要判断搞一下。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 #include<queue> 9 #include<vector> 10 using namespace std; 11 12 typedef long long LL; 13 const int N=500010,M=2*N; 14 const LL INF=(LL)1e15; 15 int n,m,len,ql,Ql; 16 int first[N],c[N],t[N],fa[N],in[N],usd[N],q[N],Q[N]; 17 LL res[N],ned[N],dis[N]; 18 struct node{ 19 int x,y,next;LL d; 20 }a[M]; 21 22 bool cmp1(int x,int y){return res[x]>res[y];} 23 bool cmp2(int x,int y){return ned[x]>ned[y];} 24 LL minn(LL x,LL y){return x<y ? x:y;} 25 26 void ins(int x,int y,LL d) 27 { 28 a[++len].x=x;a[len].y=y;a[len].d=d; 29 a[len].next=first[x];first[x]=len; 30 } 31 32 int findfa(int x) 33 { 34 if(fa[x]!=x) fa[x]=findfa(fa[x]); 35 return fa[x]; 36 } 37 38 void dfs(int x,int f) 39 { 40 if(f!=1) fa[findfa(x)]=findfa(f); 41 for(int i=first[x];i;i=a[i].next) 42 { 43 int y=a[i].y; 44 if(y==f) continue; 45 dis[y]=dis[x]+a[i].d; 46 ned[y]=a[i].d; 47 dfs(y,x); 48 } 49 } 50 51 LL DFS(int x,int f,LL d,int &cnt) 52 { 53 LL now,ans=INF;int son=0; 54 if(t[x]) ans=dis[x]; 55 bool bk=0,ok=1; 56 for(int i=first[x];i;i=a[i].next) 57 { 58 int y=a[i].y; 59 if(y==f) continue; 60 son++; 61 now=DFS(y,x,d,cnt); 62 if(now-d <= dis[x]) bk=1; 63 if(now-d > dis[y]) ok=0; 64 ans=minn(ans,now); 65 } 66 if(!son) 67 { 68 if(ans>=INF && f==1) {cnt++;Q[++Ql]=x;} 69 } 70 else 71 { 72 if(!bk && !ok && f==1) {cnt++;Q[++Ql]=x;} 73 } 74 return ans; 75 } 76 77 bool check(LL d) 78 { 79 ql=0;Ql=0; 80 memset(t,0,sizeof(t)); 81 memset(res,0,sizeof(res)); 82 memset(in,0,sizeof(in)); 83 memset(usd,0,sizeof(usd)); 84 int x,y,sum=0,cnt=0; 85 for(int i=1;i<=m;i++) 86 { 87 if(d>dis[c[i]]) 88 { 89 sum++; 90 res[i]=d-dis[c[i]]; 91 in[fa[c[i]]]++; 92 q[++ql]=i; 93 } 94 else t[c[i]]++; 95 } 96 // for(LL i=1;i<=n;i++) printf("dis %lld = %lld\n",i,t[i]); 97 // for(LL i=1;i<=n;i++) printf("dis %lld = %lld\n",i,dis[i]); 98 DFS(1,0,d,cnt); 99 if(cnt>sum) return 0; 100 int i=1,j=1;bool bk=1; 101 sort(q+1,q+1+ql,cmp1); 102 sort(Q+1,Q+1+Ql,cmp2); 103 while(i<=Ql) 104 { 105 x=Q[i];i++; 106 if(in[x]-usd[x]>=1) usd[x]++; 107 else 108 { 109 y=q[j]; 110 while(in[fa[c[y]]]==usd[fa[c[y]]]) 111 { 112 in[fa[c[y]]]--; 113 usd[fa[c[y]]]--; 114 j++; 115 y=q[j]; 116 } 117 if(res[y]<ned[x]) {bk=0;break;} 118 j++;in[fa[c[y]]]--; 119 } 120 } 121 return bk; 122 } 123 124 int main() 125 { 126 freopen("a.in","r",stdin); 127 scanf("%d",&n); 128 int x,y,cnt; 129 LL d,l=0,r=0,mid; 130 len=0; 131 memset(first,0,sizeof(first)); 132 for(int i=1;i<=n;i++) fa[i]=i; 133 for(int i=1;i<n;i++) 134 { 135 scanf("%d%d%lld",&x,&y,&d); 136 r+=d; 137 ins(x,y,d); 138 ins(y,x,d); 139 } 140 ned[1]=0;dis[1]=0;dfs(1,0); 141 scanf("%d",&m); 142 for(int i=1;i<=m;i++) scanf("%d",&c[i]); 143 cnt=0; 144 for(int i=1;i<=n;i++) 145 { 146 findfa(i); 147 if(fa[i]==i) cnt++; 148 } 149 if(m<cnt) printf("-1\n"); 150 else 151 { 152 while(l<r) 153 { 154 mid=(l+r)/2; 155 if(check(mid)) r=mid; 156 else l=mid+1; 157 } 158 printf("%lld\n",l); 159 } 160 return 0; 161 }
2013d1t1 转圈游戏
模拟题。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 using namespace std; 9 10 typedef long long LL; 11 const int N=1000010; 12 13 LL gcd(LL x,LL y) 14 { 15 if(y==0) return x; 16 return gcd(y,x%y); 17 } 18 19 LL lcm(LL x,LL y) 20 { 21 LL g=gcd(x,y); 22 return (x/g)*y; 23 } 24 25 LL quickpow(LL x,LL y,LL mod) 26 { 27 LL ans=1; 28 while(y) 29 { 30 if(y&1) ans=ans*x%mod; 31 x=x*x%mod; 32 y/=2; 33 } 34 return ans; 35 } 36 37 int main() 38 { 39 freopen("a.in","r",stdin); 40 LL n,m,k,x,len,c; 41 scanf("%lld%lld%lld%lld",&n,&m,&k,&x); 42 len=lcm(n,m); 43 c=len/m; 44 k=quickpow(10,k,c); 45 printf("%lld\n",(x+k*m)%n); 46 return 0; 47 }
2013d1t2 火柴排队
贪心。转化为求逆序对。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 using namespace std; 9 10 const int N=110000,mod=99999997; 11 int n,c[N]; 12 struct node{ 13 int d,id,iid; 14 }a[N],b[N]; 15 16 bool cmp_d(node x,node y){ 17 if(x.d!=y.d) return x.d<y.d; 18 return x.id<y.id; 19 } 20 21 bool cmp_id(node x,node y){return x.id<y.id;} 22 23 void add(int x) 24 { 25 for(int i=x;i>=1;i-=(i&(-i))) c[i]++; 26 } 27 int getsum(int x) 28 { 29 int ans=0; 30 for(int i=x;i<=n;i+=(i&(-i))) ans+=c[i]; 31 return ans; 32 } 33 34 int main() 35 { 36 freopen("a.in","r",stdin); 37 scanf("%d",&n); 38 for(int i=1;i<=n;i++) 39 { 40 scanf("%d",&a[i].d); 41 a[i].id=i; 42 } 43 sort(a+1,a+1+n,cmp_d); 44 for(int i=1;i<=n;i++) 45 { 46 scanf("%d",&b[i].d); 47 b[i].id=i; 48 } 49 sort(b+1,b+1+n,cmp_d); 50 for(int i=1;i<=n;i++) 51 { 52 b[i].iid=a[i].id; 53 } 54 sort(b+1,b+1+n,cmp_id); 55 memset(c,0,sizeof(c)); 56 int ans=0; 57 for(int i=1;i<=n;i++) 58 { 59 ans=(ans+getsum(b[i].iid))%mod; 60 add(b[i].iid); 61 } 62 printf("%d\n",ans); 63 return 0; 64 }
2013d1t3 货车运输
最大生成树+树链剖分。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 #include<queue> 9 using namespace std; 10 11 const int N=11000,M=110000,INF=(int)1e9; 12 int n,m,num,al,bl,tl,ql; 13 int af[N],bf[N],fa[N],f[N],dfn[N],dep[N],size[N],top[N],zs[N],tof[N]; 14 bool in[N]; 15 struct node{int x,y,d,bk,next;}a[M],b[M]; 16 struct trnode{int l,r,lc,rc,d;}t[2*N]; 17 deque<int> q; 18 19 int minn(int x,int y){return x<y ? x:y;} 20 21 int findfa(int x) 22 { 23 if(fa[x]!=x) fa[x]=findfa(fa[x]); 24 return fa[x]; 25 } 26 27 void ins_a(int x,int y,int d) 28 { 29 a[++al].x=x;a[al].y=y;a[al].d=d; 30 a[al].next=af[x];af[x]=al; 31 } 32 33 void ins_b(int x,int y,int d) 34 { 35 b[++bl].x=x;b[bl].y=y;b[bl].d=d;b[bl].bk=0; 36 b[bl].next=bf[x];bf[x]=bl; 37 } 38 39 bool cmp(node x,node y){return x.d>y.d;} 40 41 void kruskal() 42 { 43 sort(b+1,b+1+bl,cmp); 44 int x,y,xx,yy; 45 for(int i=1;i<=bl;i++) 46 { 47 x=b[i].x,y=b[i].y; 48 xx=findfa(x),yy=findfa(y); 49 if(xx!=yy) 50 { 51 b[i].bk=1; 52 fa[xx]=yy; 53 } 54 } 55 } 56 57 int bt(int l,int r) 58 { 59 int x=++tl; 60 t[x].l=l;t[x].r=r; 61 t[x].lc=t[x].rc=0; 62 if(l<r) 63 { 64 int mid=(l+r)/2; 65 t[x].lc=bt(l,mid); 66 t[x].rc=bt(mid+1,r); 67 int lc=t[x].lc,rc=t[x].rc; 68 t[x].d=minn(t[lc].d,t[rc].d); 69 } 70 else t[x].d=tof[l]; 71 return x; 72 } 73 74 int query(int x,int l,int r) 75 { 76 if(t[x].l==l && t[x].r==r) return t[x].d; 77 int lc=t[x].lc,rc=t[x].rc,mid=(t[x].l+t[x].r)/2; 78 if(r<=mid) return query(lc,l,r); 79 if(l>mid) return query(rc,l,r); 80 return minn(query(lc,l,mid),query(rc,mid+1,r)); 81 } 82 83 void dfs(int x,int ff) 84 { 85 size[x]=1; 86 zs[x]=0; 87 f[x]=ff; 88 dep[x]=dep[ff]+1; 89 for(int i=af[x];i;i=a[i].next) 90 { 91 int y=a[i].y; 92 if(y==ff) continue; 93 dfs(y,x); 94 size[x]+=size[y]; 95 if(zs[x]==0 || size[y]>size[zs[x]]) zs[x]=y; 96 } 97 } 98 99 void fd_top(int x,int ff) 100 { 101 dfn[x]=++num; 102 if(zs[x]) 103 { 104 top[zs[x]]=top[x]; 105 fd_top(zs[x],x); 106 } 107 for(int i=af[x];i;i=a[i].next) 108 { 109 int y=a[i].y; 110 if(y==ff) continue; 111 if(y==zs[x]) 112 { 113 tof[dfn[zs[x]]]=a[i].d; 114 continue; 115 } 116 top[y]=y; 117 fd_top(y,x); 118 tof[dfn[y]]=a[i].d; 119 } 120 } 121 122 int solve(int x,int y) 123 { 124 int tx=top[x],ty=top[y],ans=INF; 125 while(tx!=ty) 126 { 127 if(dep[tx]<dep[ty]) swap(x,y),swap(tx,ty); 128 ans=minn(ans,query(1,dfn[tx],dfn[x])); 129 x=f[top[x]];tx=top[x]; 130 } 131 if(x==y) return ans; 132 if(dep[x]<dep[y]) swap(x,y); 133 ans=minn(ans,query(1,dfn[y]+1,dfn[x])); 134 return ans; 135 } 136 137 int main() 138 { 139 freopen("a.in","r",stdin); 140 freopen("a.out","w",stdout); 141 scanf("%d%d",&n,&m); 142 int x,y,d; 143 al=0;bl=0; 144 memset(af,0,sizeof(af)); 145 memset(bf,0,sizeof(bf)); 146 for(int i=1;i<=n;i++) fa[i]=i; 147 for(int i=1;i<=m;i++) 148 { 149 scanf("%d%d%d",&x,&y,&d); 150 ins_b(x,y,d); 151 ins_b(y,x,d); 152 } 153 kruskal(); 154 for(int i=1;i<=bl;i++) 155 { 156 if(b[i].bk) 157 { 158 ins_a(b[i].x,b[i].y,b[i].d); 159 ins_a(b[i].y,b[i].x,b[i].d); 160 } 161 } 162 tl=0;num=0;dep[0]=0;size[0]=0; 163 for(int i=1;i<=n;i++) 164 { 165 if(fa[i]==i) 166 { 167 dfs(i,0); 168 top[i]=i;fd_top(i,0); 169 } 170 } 171 bt(1,n); 172 scanf("%d",&ql); 173 for(int i=1;i<=ql;i++) 174 { 175 scanf("%d%d",&x,&y); 176 if(findfa(x)!=findfa(y)) printf("-1\n"); 177 else printf("%d\n",solve(x,y)); 178 } 179 return 0; 180 }
2013d2t1 积木大赛
取差值即可。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 #include<queue> 9 using namespace std; 10 11 int main() 12 { 13 freopen("a.in","r",stdin); 14 int n,x,p,ans; 15 scanf("%d",&n); 16 p=0;ans=0; 17 for(int i=1;i<=n;i++) 18 { 19 scanf("%d",&x); 20 if(x>p) ans+=x-p; 21 p=x; 22 } 23 printf("%d\n",ans); 24 return 0; 25 }
2013d2t2 花匠
贪心。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 #include<queue> 9 using namespace std; 10 11 const int N=110000,INF=(int)1e9; 12 int n,a[N]; 13 14 int maxx(int x,int y){return x>y ? x:y;} 15 16 int main() 17 { 18 freopen("a.in","r",stdin); 19 scanf("%d",&n); 20 for(int i=1;i<=n;i++) 21 { 22 scanf("%d",&a[i]); 23 } 24 int ans=0,now=0,last=0; 25 a[0]=0; 26 for(int i=1;i<=n;i++) 27 { 28 if(now&1) 29 { 30 if(a[i]<a[last]) now++,last=i; 31 else if(a[i]>a[last]) last=i; 32 } 33 else 34 { 35 if(a[i]>a[last]) now++,last=i; 36 else if(a[i]<a[last]) last=i; 37 } 38 } 39 // printf("now = %d\n",now); 40 ans=now;now=0;last=0; 41 a[0]=INF; 42 for(int i=1;i<=n;i++) 43 { 44 if(!(now&1)) 45 { 46 if(a[i]<a[last]) now++,last=i; 47 else if(a[i]>a[last]) last=i; 48 } 49 else 50 { 51 if(a[i]>a[last]) now++,last=i; 52 else if(a[i]<a[last]) last=i; 53 } 54 } 55 ans=maxx(ans,now); 56 printf("%d\n",ans); 57 return 0; 58 }
2013d2t3 华容道
bfs神题。反正我给跪了,调了好久才调出来。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 #include<queue> 9 using namespace std; 10 11 const int N=60,S=51,INF=(int)1e9; 12 int n,m,ans,xed,yed,tot,len,first[4*N*N],dis[4*N*N],id[N][N][5]; 13 int dx[5]={0,-1,1,0,0}; 14 int dy[5]={0,0,0,-1,1}; 15 bool map[N][N],vis[N][N],in[4*N*N]; 16 struct node{int x,y,d,next;}a[100010]; 17 struct nd{int x,y,sum;}b[4*N*N]; 18 queue<int> q; 19 queue<nd> Q; 20 21 int minn(int x,int y){return x<y ? x:y;} 22 23 void ins(int x,int y,int d) 24 { 25 a[++len].x=x;a[len].y=y;a[len].d=d; 26 a[len].next=first[x];first[x]=len; 27 } 28 29 bool check(nd k) 30 { 31 if(k.x<1 || k.y<1 || k.x>n || k.y>m || !map[k.x][k.y]) return 0; 32 return 1; 33 } 34 35 void fd(int x0,int y0,int x1,int y1) 36 { 37 nd t,k; 38 while(!Q.empty()) Q.pop(); 39 memset(vis,0,sizeof(vis)); 40 t.x=x0;t.y=y0;t.sum=0; 41 vis[t.x][t.y]=1; 42 Q.push(t); 43 while(!Q.empty()) 44 { 45 t=Q.front();Q.pop(); 46 for(int i=1;i<=4;i++) 47 { 48 k.x=t.x+dx[i]; 49 k.y=t.y+dy[i]; 50 k.sum=t.sum+1; 51 if(!check(k)) continue; 52 if(k.x==x1 && k.y==y1) 53 { 54 for(int j=1;j<=4;j++) 55 if(x1+dx[j]==t.x && y1+dy[j]==t.y) {ins(tot,id[x1][y1][j],t.sum);break;} 56 continue; 57 } 58 if(!vis[k.x][k.y]) vis[k.x][k.y]=1,Q.push(k); 59 } 60 } 61 } 62 63 void bfs(int x0,int y0) 64 { 65 nd t,k; 66 for(int i=1;i<=4;i++) 67 { 68 t.x=x0+dx[i]; 69 t.y=y0+dy[i]; 70 if(!check(t)) continue; 71 for(int j=1;j<=4;j++) 72 { 73 if(t.x+dx[j]==x0 && t.y+dy[j]==y0) {ins(id[x0][y0][i],id[t.x][t.y][j],1);break;} 74 } 75 while(!Q.empty()) Q.pop(); 76 memset(vis,0,sizeof(vis)); 77 vis[t.x][t.y]=1; 78 t.sum=0; 79 Q.push(t); 80 while(!Q.empty()) 81 { 82 t=Q.front();Q.pop(); 83 for(int l=1;l<=4;l++) 84 { 85 k.x=t.x+dx[l]; 86 k.y=t.y+dy[l]; 87 k.sum=t.sum+1; 88 if(!check(k)) continue; 89 if(k.x==x0 && k.y==y0) 90 { 91 for(int j=1;j<=4;j++) 92 if(x0+dx[j]==t.x && y0+dy[j]==t.y) {if(i!=j) ins(id[x0][y0][i],id[x0][y0][j],t.sum);break;} 93 continue; 94 } 95 if(!vis[k.x][k.y]) vis[k.x][k.y]=1,Q.push(k); 96 } 97 } 98 } 99 } 100 101 int spfa(int st) 102 { 103 while(!q.empty()) q.pop(); 104 memset(dis,63,sizeof(dis)); 105 memset(in,0,sizeof(in)); 106 q.push(st);dis[st]=0;in[st]=1; 107 while(!q.empty()) 108 { 109 int x=q.front();in[x]=0;q.pop(); 110 for(int i=first[x];i;i=a[i].next) 111 { 112 int y=a[i].y; 113 if(dis[y]>dis[x]+a[i].d) 114 { 115 dis[y]=dis[x]+a[i].d; 116 if(!in[y]) in[y]=1,q.push(y); 117 } 118 } 119 } 120 int ans=INF; 121 for(int i=1;i<=4;i++) 122 if(id[xed][yed][i]) ans=minn(ans,dis[id[xed][yed][i]]); 123 if(ans<INF) return ans; 124 return -1; 125 } 126 127 int main() 128 { 129 // freopen("a.in","r",stdin); 130 // freopen("a.out","w",stdout); 131 freopen("puzzle.in","r",stdin); 132 freopen("puzzle.out","w",stdout); 133 int x,y,x0,y0,x1,y1,K; 134 scanf("%d%d%d",&n,&m,&K); 135 for(int i=1;i<=n;i++) 136 for(int j=1;j<=m;j++) 137 scanf("%d",&map[i][j]); 138 tot=0;len=0; 139 memset(first,0,sizeof(first)); 140 for(int i=1;i<=n;i++) 141 for(int j=1;j<=m;j++) 142 for(int k=1;k<=4;k++) 143 { 144 x=i+dx[k]; 145 y=j+dy[k]; 146 if(x<1 || y<1 || x>n || y>m) continue; 147 if(map[i][j] && map[x][y]) 148 { 149 id[i][j][k]=++tot; 150 } 151 } 152 for(int i=1;i<=n;i++) 153 for(int j=1;j<=m;j++) 154 if(map[i][j]) bfs(i,j); 155 for(int i=1;i<=K;i++) 156 { 157 scanf("%d%d%d%d%d%d",&x0,&y0,&x1,&y1,&xed,&yed); 158 if(x1==xed && y1==yed) {printf("0\n");continue;} 159 tot++; 160 fd(x0,y0,x1,y1); 161 printf("%d\n",spfa(tot)); 162 } 163 return 0; 164 }
2014d1t1 石头剪刀布
模拟题。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 using namespace std; 9 10 const int N=210; 11 int n,l1,l2,a[N],b[N]; 12 13 int check(int x,int y) 14 { 15 if(x==y) return 0; 16 if(x==0 && (y==1 || y==4)) return 0; 17 if(x==1 && (y==2 || y==4)) return 0; 18 if(x==2 && (y==0 || y==3)) return 0; 19 if(x==3 && (y==0 || y==1)) return 0; 20 if(x==4 && (y==2 || y==3)) return 0; 21 return 1; 22 } 23 24 int main() 25 { 26 freopen("a.in","r",stdin); 27 scanf("%d%d%d",&n,&l1,&l2); 28 for(int i=1;i<=l1;i++) 29 { 30 scanf("%d",&a[i]); 31 } 32 for(int i=1;i<=l2;i++) 33 { 34 scanf("%d",&b[i]); 35 } 36 int j=1,k=1,ans1=0,ans2=0; 37 for(int i=1;i<=n;i++) 38 { 39 if(j==l1+1) j=1; 40 if(k==l2+1) k=1; 41 ans1+=check(a[j],b[k]); 42 ans2+=check(b[k],a[j]); 43 j++;k++; 44 } 45 printf("%d %d\n",ans1,ans2); 46 return 0; 47 }
2014d1t2 联合权值
树上dfs乱搞。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 using namespace std; 9 10 const int N=210000,M=2*210000,mod=10007; 11 int n,m,len,ans_mx,ans_sum; 12 int first[N],f[N],w[N],sum[N]; 13 struct node{ 14 int x,y,next; 15 }a[M]; 16 17 int maxx(int x,int y){return x>y ? x:y;} 18 19 void ins(int x,int y) 20 { 21 a[++len].x;a[len].y=y; 22 a[len].next=first[x];first[x]=len; 23 } 24 25 void dfs(int x,int fa) 26 { 27 f[x]=fa; 28 sum[x]=0; 29 int mx1=0,mx2=0; 30 for(int i=first[x];i;i=a[i].next) 31 { 32 int y=a[i].y; 33 if(y==fa) continue; 34 sum[x]=(sum[x]+w[y])%mod; 35 if(w[y]>mx1) mx2=mx1,mx1=w[y]; 36 else if(w[y]>mx2) mx2=w[y]; 37 dfs(y,x); 38 } 39 ans_mx=maxx(ans_mx,mx1*mx2); 40 } 41 42 void DFS(int x) 43 { 44 ans_sum=(ans_sum+w[x]*(((sum[f[x]]-w[x])%mod+mod)%mod)%mod)%mod; 45 ans_sum=(ans_sum+2*w[x]*w[f[f[x]]]%mod)%mod; 46 ans_mx=maxx(ans_mx,w[x]*w[f[f[x]]]); 47 for(int i=first[x];i;i=a[i].next) 48 { 49 int y=a[i].y; 50 if(y==f[x]) continue; 51 DFS(y); 52 } 53 } 54 55 int main() 56 { 57 freopen("a.in","r",stdin); 58 scanf("%d",&n); 59 int x,y; 60 len=0; 61 ans_mx=0;ans_sum=0; 62 memset(f,0,sizeof(f)); 63 memset(first,0,sizeof(first)); 64 for(int i=1;i<n;i++) 65 { 66 scanf("%d%d",&x,&y); 67 ins(x,y); 68 ins(y,x); 69 } 70 w[0]=0; 71 for(int i=1;i<=n;i++) 72 { 73 scanf("%d",&w[i]); 74 } 75 sum[0]=w[1]; 76 dfs(1,0); 77 DFS(1); 78 printf("%d %d\n",ans_mx,ans_sum); 79 return 0; 80 }
2014d1t3 飞扬的小鸟
各种细节的dp
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 #include<queue> 9 using namespace std; 10 11 const int N=11000,M=1100,INF=(int)1e9; 12 int n,m,t,sl[2],s[2][N],in[N],f[2][N],sum[N],up[N],down[N],l[N],r[N]; 13 struct node{ 14 int x,l,r; 15 }a[N]; 16 queue<int> q[2]; 17 18 bool cmp(node x,node y){return x.x<y.x;} 19 20 int minn(int x,int y){return x<y ? x:y;} 21 22 int main() 23 { 24 freopen("a.in","r",stdin); 25 freopen("a.out","w",stdout); 26 scanf("%d%d%d",&n,&m,&t); 27 sum[0]=0; 28 memset(l,-1,sizeof(l)); 29 memset(r,-1,sizeof(r)); 30 for(int i=0;i<n;i++) 31 { 32 scanf("%d%d",&up[i],&down[i]); 33 if(i-1>=0) sum[i]=sum[i-1]+down[i-1]; 34 } 35 up[n]=INF;down[n]=INF; 36 // for(int i=0;i<n;i++) printf("sum %d = %d\n",i,sum[i]); 37 38 for(int i=1;i<=t;i++) 39 { 40 scanf("%d%d%d",&a[i].x,&a[i].l,&a[i].r); 41 l[a[i].x]=a[i].l; 42 r[a[i].x]=a[i].r; 43 } 44 sort(a+1,a+1+t,cmp); 45 46 while(!q[0].empty()) q[0].pop(); 47 while(!q[1].empty()) q[1].pop(); 48 sl[0]=sl[1]=0; 49 memset(in,0,sizeof(in)); 50 for(int i=0;i<=m;i++) f[0][i]=f[1][i]=INF; 51 52 int x,y,now=0,j=1,ans=INF,mx=0; 53 for(int i=0;i<=m;i++) 54 { 55 if(j<=t && a[j].r-1 < i-(sum[a[j].x]-sum[0])) continue; 56 f[0][i]=0; 57 // printf("f 0 %d = %d\n",i,f[0][i]); 58 s[0][++sl[0]]=i; 59 q[0].push(i); 60 } 61 for(int i=0;i<=n;i++) 62 { 63 if(i!=0) 64 { 65 now=1-now; 66 for(int k=1;k<=sl[1-now];k++) 67 { 68 f[1-now][s[1-now][k]]=INF; 69 } 70 sl[1-now]=0; 71 } 72 while(j<=t && a[j].x<=i) j++; 73 74 while(!q[now].empty()) 75 { 76 x=q[now].front();q[now].pop(); 77 printf("f %d %d = %d\n",i,x,f[now][x]); 78 mx=i; 79 if(i==n) ans=minn(ans,f[now][x]); 80 for(int k=1;k<=((m-x)/up[i])+1;k++) 81 { 82 y=minn(x+k*up[i],m); 83 if(j<=t && (a[j].r-1 < y-(sum[a[j].x]-sum[i]))) continue; 84 if(l[i+1]!=-1 && (y<=l[i+1] || y>=r[i+1])) continue; 85 f[1-now][y]=minn(f[1-now][y],f[now][x]+k); 86 if(!in[y]) 87 { 88 in[y]=1; 89 s[1-now][++sl[1-now]]=y; 90 q[1-now].push(y); 91 } 92 } 93 y=x-down[i]; 94 if(y>0 && !(j<=t && (a[j].r-1 < y-(sum[a[j].x]-sum[i]))) && !(l[i+1]!=-1 && (y<=l[i+1] || y>=r[i+1]))) 95 { 96 f[1-now][y]=minn(f[1-now][y],f[now][x]); 97 if(!in[y]) 98 { 99 in[y]=1; 100 s[1-now][++sl[1-now]]=y; 101 q[1-now].push(y); 102 } 103 } 104 } 105 for(int k=1;k<=sl[1-now];k++) in[s[1-now][k]]=0; 106 } 107 if(ans==INF) 108 { 109 printf("0\n"); 110 int k=0; 111 for(int i=1;i<=t;i++) 112 { 113 if(a[i].x<=mx) k=i; 114 else break; 115 } 116 printf("%d\n",k); 117 } 118 else 119 { 120 printf("1\n"); 121 printf("%d\n",ans); 122 } 123 return 0; 124 }
2014 d2t1 无线网络发射器
枚举+树状数组
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 #include<queue> 9 using namespace std; 10 11 const int N=210,M=210,mx=200; 12 int l,n,c[N][N]; 13 14 void add(int x,int y,int d) 15 { 16 for(int i=x;i<=mx;i+=(i&(-i))) 17 for(int j=y;j<=mx;j+=(j&(-j))) 18 c[i][j]+=d; 19 } 20 int getsum(int x,int y) 21 { 22 int ans=0; 23 for(int i=x;i>=1;i-=(i&(-i))) 24 for(int j=y;j>=1;j-=(j&(-j))) 25 ans+=c[i][j]; 26 return ans; 27 } 28 29 int main() 30 { 31 freopen("a.in","r",stdin); 32 scanf("%d%d",&l,&n); 33 int x,y,d; 34 memset(c,0,sizeof(c)); 35 for(int i=1;i<=n;i++) 36 { 37 scanf("%d%d%d",&x,&y,&d); 38 x++;y++; 39 add(x,y,d); 40 } 41 int now,ans=0,sum=0; 42 for(int i=1;i<=129;i++) 43 for(int j=1;j<=129;j++) 44 { 45 now=getsum(i+l,j+l)-getsum(i-l-1,j+l)-getsum(i+l,j-l-1)+getsum(i-l-1,j-l-1); 46 // if(now>20) printf("i = %d j = %d now = %d\n",i,j,now); 47 if(now>ans) ans=now,sum=1; 48 else if(now==ans) sum++; 49 } 50 printf("%d %d\n",sum,ans); 51 return 0; 52 }
2014d2t2 寻找道路
反向找一遍,然后spfa
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 #include<queue> 9 using namespace std; 10 11 const int N=11000,M=210000,INF=(int)1e9; 12 int n,m,al,bl,af[N],bf[N],dis[N]; 13 bool c[N],vis[N],in[N]; 14 struct node{ 15 int x,y,next; 16 }a[M],b[M]; 17 queue<int> q; 18 19 void ins_a(int x,int y) 20 { 21 a[++al].x=x;a[al].y=y; 22 a[al].next=af[x];af[x]=al; 23 } 24 25 void ins_b(int x,int y) 26 { 27 b[++bl].x=x;b[bl].y=y; 28 b[bl].next=bf[x];bf[x]=bl; 29 } 30 31 void bfs(int st) 32 { 33 while(!q.empty()) q.pop(); 34 memset(vis,0,sizeof(vis)); 35 q.push(st);vis[st]=1; 36 while(!q.empty()) 37 { 38 int x=q.front();q.pop(); 39 for(int i=af[x];i;i=a[i].next) 40 { 41 int y=a[i].y; 42 if(!vis[y]) 43 { 44 vis[y]=1; 45 q.push(y); 46 } 47 } 48 } 49 } 50 51 void spfa(int st) 52 { 53 while(!q.empty()) q.pop(); 54 memset(dis,63,sizeof(dis)); 55 memset(in,0,sizeof(in)); 56 q.push(st);dis[st]=0;in[st]=1; 57 while(!q.empty()) 58 { 59 int x=q.front();in[x]=0;q.pop(); 60 for(int i=af[x];i;i=a[i].next) 61 { 62 int y=a[i].y; 63 if(dis[y]>dis[x]+1) 64 { 65 dis[y]=dis[x]+1; 66 if(!in[y]) in[y]=1,q.push(y); 67 } 68 } 69 } 70 } 71 72 int main() 73 { 74 freopen("a.in","r",stdin); 75 int x,y,st,ed; 76 al=0;bl=0; 77 memset(af,0,sizeof(af)); 78 memset(bf,0,sizeof(bf)); 79 memset(c,0,sizeof(c)); 80 scanf("%d%d",&n,&m); 81 for(int i=1;i<=m;i++) 82 { 83 scanf("%d%d",&x,&y); 84 ins_a(y,x); 85 ins_b(x,y); 86 } 87 scanf("%d%d",&st,&ed); 88 bfs(ed); 89 for(int i=1;i<=n;i++) 90 { 91 if(i==ed || bf[i]) c[i]=1; 92 else c[i]=0; 93 for(int j=bf[i];j;j=b[j].next) 94 { 95 if(!vis[b[j].y]) {c[i]=0;break;} 96 } 97 } 98 al=0; 99 memset(af,0,sizeof(af)); 100 for(int i=1;i<=bl;i++) 101 { 102 if(c[b[i].x] && c[b[i].y]) ins_a(b[i].x,b[i].y); 103 } 104 spfa(st); 105 if(dis[ed]>=INF) printf("-1\n"); 106 else printf("%d\n",dis[ed]); 107 return 0; 108 }
2014 d2t3 解方程
70分算法。mod几个质数。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 #include<queue> 9 using namespace std; 10 11 typedef long long LL; 12 const int N=110,M=11000,S=10000010,MX=100000; 13 int n,m; 14 struct node{ 15 int tmp,sl,s[M]; 16 }a[N]; 17 LL b[N],p[9]={0,93257,89371,89213,49451,47207,74521,21277,21433};//{0,2147483647,100000007,2013265921}; 18 bool c[S]; 19 char s[M]; 20 21 int minn(int x,int y){return x<y ? x:y;} 22 23 LL cal_mod(node x,LL y) 24 { 25 LL now=0,tmp=(LL)x.tmp; 26 for(int i=1;i<=x.sl;i++) 27 { 28 now=now*10+(LL)x.s[i]; 29 if(now>=y) now%=y; 30 } 31 return now*tmp; 32 } 33 34 int main() 35 { 36 freopen("a.in","r",stdin); 37 scanf("%lld%lld",&n,&m); 38 int sl; 39 for(int i=0;i<=n;i++) 40 { 41 scanf("%s",s); 42 sl=strlen(s); 43 a[i].sl=0; 44 if(s[0]=='-') 45 { 46 a[i].tmp=-1; 47 for(int j=1;j<sl;j++) a[i].s[++a[i].sl]=s[j]-'0'; 48 } 49 else 50 { 51 a[i].tmp=1; 52 for(int j=0;j<sl;j++) a[i].s[++a[i].sl]=s[j]-'0'; 53 } 54 } 55 int cnt=0; 56 memset(c,1,sizeof(c)); 57 for(int k=1;k<=8;k++) 58 { 59 for(int i=0;i<=n;i++) 60 { 61 b[i]=cal_mod(a[i],p[k]); 62 // printf("b %d = %lld\n",i,b[i]); 63 } 64 for(int i=1;i<=minn(m,MX);i++) 65 { 66 if(!c[i]) continue; 67 LL x=1,now=0; 68 for(int j=0;j<=n;j++) 69 { 70 now=(now+b[j]*x%p[k])%p[k]; 71 x=x*((LL)i)%p[k]; 72 } 73 if(now) c[i]=0;//ans[++cnt]=i; 74 } 75 for(int i=MX;i<=m;i++) 76 { 77 if(!c[i]) continue; 78 if(!c[i%p[k]]) c[i]=0; 79 } 80 } 81 for(int i=1;i<=m;i++) if(c[i]) cnt++; 82 printf("%d\n",cnt); 83 for(int i=1;i<=m;i++) if(c[i]) printf("%d\n",i); 84 return 0; 85 }
2015 d1t1 幻方
模拟题
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 using namespace std; 9 10 const int N=50; 11 int n,a[N][N]; 12 13 int main() 14 { 15 freopen("a.in","r",stdin); 16 scanf("%d",&n); 17 int x,y,k=1,lx=1,ly=(n/2)+1; 18 memset(a,0,sizeof(a)); 19 a[1][(n/2)+1]=1; 20 for(int i=2;i<=n*n;i++) 21 { 22 if(lx==1 && ly!=n) x=n,y=ly+1; 23 if(lx!=1 && ly==n) x=lx-1,y=1; 24 if(lx==1 && ly==n) x=lx+1,y=ly; 25 if(lx!=1 && ly!=n) 26 { 27 if(!a[lx-1][ly+1]) x=lx-1,y=ly+1; 28 else x=lx+1,y=ly; 29 } 30 a[x][y]=++k; 31 lx=x;ly=y; 32 } 33 for(int i=1;i<=n;i++) 34 { 35 for(int j=1;j<=n;j++) 36 printf("%d ",a[i][j]); 37 printf("\n"); 38 } 39 return 0; 40 }
2015 d1t2 信息传递
最重要的性质就是每个点只要一条出边。。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 using namespace std; 9 10 const int N=210000,INF=(int)1e9; 11 int n,fa[N],d[N]; 12 13 int minn(int x,int y){return x<y ? x:y;} 14 15 int findfa(int x) 16 { 17 if(fa[x]!=x) 18 { 19 int xx=fa[x]; 20 fa[x]=findfa(fa[x]); 21 d[x]=d[x]+d[xx]; 22 } 23 return fa[x]; 24 } 25 26 int main() 27 { 28 freopen("a.in","r",stdin); 29 scanf("%d",&n); 30 int x,y,xx,yy,ans=INF; 31 for(int i=1;i<=n;i++) fa[i]=i,d[i]=0; 32 for(int i=1;i<=n;i++) 33 { 34 x=i; 35 scanf("%d",&y); 36 xx=findfa(x);yy=findfa(y); 37 if(xx==yy) 38 { 39 ans=minn(ans,d[x]+d[y]+1); 40 } 41 else 42 { 43 fa[xx]=x; 44 d[xx]=d[x]; 45 fa[x]=y; 46 d[x]=1; 47 } 48 } 49 printf("%d\n",ans); 50 return 0; 51 }
2015d2t3 斗地主
搜索。然后看了别人代码用贪心。。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 using namespace std; 6 7 const int N=25,S=13,Inf=(int)1e9; 8 int n,sum[N],ans; 9 10 int getsum(int r[]) 11 { 12 int c1=0,c2=0,c3=0,c4=0,cnt=0;//cnt 带牌 13 bool bk=0; 14 if(r[0]==2) bk=1; 15 for(int i=0;i<=S;i++){ 16 if(r[i]==1) c1++; 17 if(r[i]==2) c2++; 18 if(r[i]==3) c3++; 19 if(r[i]==4) c4++; 20 } 21 while(((!bk && c2>=2) || (bk && c2-1>=2)) && c4) c2-=2,c4--,cnt++;//四带二对 22 while(((!bk && c2) || (bk && c2-1>=1)) && c3) c2--,c3--,cnt++;//三带一对 23 while(c1>=2 && c4) c1-=2,c4--,cnt++;//四带二单 24 while(c2 && c4) c2--,c4--,cnt++;//四带二单 25 while(c1 && c3) c1--,c3--,cnt++;//三带一单 26 return cnt+c1+c2+c3+c4;//带牌+单牌+对牌+三牌+四牌 27 } 28 29 void dfs(int r[],int now) 30 { 31 int t=getsum(r); 32 if(!ans || (ans && t+now<ans)) ans=t+now; 33 if(ans && now>ans) return ; 34 //三顺子 35 for(int i=2;i<S;i++) 36 { 37 int cnt=0; 38 for(int j=i;j<=S;j++) 39 { 40 if(r[j]>=3) cnt++; 41 else break; 42 } 43 if(cnt>=2) 44 { 45 for(int l=2;l<=cnt;l++) 46 { 47 for(int j=i;j<=i+l-1;j++) r[j]-=3; 48 dfs(r,now+1); 49 for(int j=i;j<=i+l-1;j++) r[j]+=3; 50 } 51 } 52 } 53 //双顺子 54 for(int i=2;i<S;i++) 55 { 56 int cnt=0; 57 for(int j=i;j<=S;j++) 58 { 59 if(r[j]>=2) cnt++; 60 else break; 61 } 62 if(cnt>=3) 63 { 64 for(int l=3;l<=cnt;l++) 65 { 66 for(int j=i;j<=i+l-1;j++) r[j]-=2; 67 dfs(r,now+1); 68 for(int j=i;j<=i+l-1;j++) r[j]+=2; 69 } 70 } 71 } 72 //单顺子 73 for(int i=2;i<S;i++) 74 { 75 int cnt=0; 76 for(int j=i;j<=S;j++) 77 { 78 if(r[j]>=1) cnt++; 79 else break; 80 } 81 if(cnt>=5) 82 for(int l=5;l<=cnt;l++) 83 { 84 for(int j=i;j<=i+l-1;j++) r[j]--; 85 dfs(r,now+1); 86 for(int j=i;j<=i+l-1;j++) r[j]++; 87 } 88 } 89 90 } 91 92 int main() 93 { 94 freopen("a.in","r",stdin); 95 // freopen("a.out","w",stdout); 96 int T; 97 scanf("%d%d",&T,&n); 98 while(T--) 99 { 100 ans=0; 101 memset(sum,0,sizeof(sum)); 102 for(int i=1;i<=n;i++) 103 { 104 int x,y; 105 scanf("%d%d",&x,&y); 106 if(x==1) x=13; 107 else if(x>=2) x--; 108 sum[x]++; 109 } 110 dfs(sum,0); 111 printf("%d\n",ans); 112 } 113 return 0; 114 }
2015 d2t1 跳石头
二分。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 using namespace std; 9 10 const int N=51000; 11 int n,m,len,a[N]; 12 13 bool check(int d) 14 { 15 int sum=0,last=0; 16 for(int i=1;i<=n;i++) 17 { 18 if(a[i]-last<d) sum++; 19 else last=a[i]; 20 } 21 if(len-last<d) sum++; 22 if(sum<=m) return 1; 23 return 0; 24 } 25 26 int main() 27 { 28 freopen("a.in","r",stdin); 29 scanf("%d%d%d",&len,&n,&m); 30 for(int i=1;i<=n;i++) 31 { 32 scanf("%d",&a[i]); 33 } 34 int l=1,r=len,mid; 35 while(l<r) 36 { 37 mid=(l+r+1)/2; 38 if(check(mid)) l=mid; 39 else r=mid-1; 40 } 41 printf("%d\n",l); 42 return 0; 43 }
2015d2t2 子串
四维dp。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 using namespace std; 9 10 const int N=1100,M=210,mod=1000000007; 11 int n,m,K,f[2][M][M][2]; 12 char a[N],b[N]; 13 14 void ad(int &x,int y){ 15 x=(x+y)%mod; 16 return; 17 } 18 19 int main() 20 { 21 freopen("a.in","r",stdin); 22 scanf("%d%d%d",&n,&m,&K); 23 scanf("%s%s",a+1,b+1); 24 memset(f,0,sizeof(f)); 25 // f[0][0][0][0]=1; 26 int x,now=0,ans=0; 27 for(int i=0;i<=n;i++) 28 { 29 now=1-now; 30 memset(f[1-now],0,sizeof(f[1-now])); 31 if(i==0) f[now][0][0][0]=1; 32 for(int j=0;j<=m;j++) 33 for(int k=0;k<=K;k++) 34 for(int l=0;l<=1;l++) 35 { 36 x=f[now][j][k][l]; 37 // printf("f %d %d %d %d = %d\n",i,j,k,l,x); 38 if(i==n && j==m && k==K) ad(ans,x); 39 if(x==0) continue; 40 if(l==1) 41 { 42 if(i+1<=n && j+1<=m && a[i+1]==b[j+1]) 43 { 44 ad(f[1-now][j+1][k][1],x); 45 ad(f[1-now][j+1][k+1][1],x); 46 } 47 ad(f[1-now][j][k][0],x); 48 } 49 else 50 { 51 if(i+1<=n && j+1<=m && a[i+1]==b[j+1]) ad(f[1-now][j+1][k+1][1],x); 52 ad(f[1-now][j][k][0],x); 53 } 54 } 55 } 56 printf("%d\n",ans); 57 return 0; 58 }
2015d2t3 运输计划
二分d,有k条路径比d大,找一条边是这k条路径的公共边让它减了之后满足条件。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<set> 8 using namespace std; 9 10 const int N=310000,M=2*310000,S=50,D=30; 11 int n,m,len; 12 int t[N],dep[N],dis[N],first[N],f[N][S]; 13 struct node{ 14 int x,y,d,next; 15 }a[M]; 16 struct qnode{ 17 int x,y,z,d; 18 }q[N]; 19 20 int maxx(int x,int y){return x>y ? x:y;} 21 22 void ins(int x,int y,int d) 23 { 24 a[++len].x=x;a[len].y=y;a[len].d=d; 25 a[len].next=first[x];first[x]=len; 26 } 27 28 void dfs(int x,int fa) 29 { 30 // printf("x = %d fa = %d\n",x,fa); 31 f[x][0]=fa; 32 dep[x]=dep[fa]+1; 33 for(int i=first[x];i;i=a[i].next) 34 { 35 int y=a[i].y; 36 if(y==fa) continue; 37 dis[y]=dis[x]+a[i].d; 38 dfs(y,x); 39 } 40 } 41 42 void lca_init() 43 { 44 for(int j=1;j<=D;j++) 45 for(int i=1;i<=n;i++) 46 f[i][j]=f[f[i][j-1]][j-1]; 47 } 48 49 int lca_query(int x,int y) 50 { 51 if(dep[x]<dep[y]) swap(x,y); 52 for(int i=D;i>=0;i--) 53 { 54 if(dep[f[x][i]]>=dep[y]) x=f[x][i]; 55 } 56 if(x==y) return x; 57 for(int i=D;i>=0;i--) 58 { 59 if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i]; 60 } 61 return f[x][0]; 62 } 63 64 void DFS(int x,int fa,int sum,int &dmx) 65 { 66 for(int i=first[x];i;i=a[i].next) 67 { 68 int y=a[i].y; 69 if(y==fa) continue; 70 DFS(y,x,sum,dmx); 71 if(t[y]>=sum) dmx=maxx(dmx,a[i].d); 72 t[x]+=t[y]; 73 t[y]=0; 74 } 75 } 76 77 bool check(int d) 78 { 79 int qmx=0,sum=0; 80 for(int i=1;i<=m;i++) 81 { 82 if(q[i].d>d) 83 { 84 t[q[i].x]++; 85 t[q[i].y]++; 86 t[q[i].z]-=2; 87 sum++; 88 qmx=maxx(qmx,q[i].d); 89 } 90 } 91 int dmx=0; 92 DFS(1,0,sum,dmx); 93 if(qmx-dmx<=d) return 1; 94 return 0; 95 } 96 97 int main() 98 { 99 freopen("a.in","r",stdin); 100 scanf("%d%d",&n,&m); 101 int x,y,d; 102 len=0; 103 memset(f,0,sizeof(f)); 104 memset(t,0,sizeof(t)); 105 memset(dep,0,sizeof(dep)); 106 memset(dis,0,sizeof(dis)); 107 memset(first,0,sizeof(first)); 108 for(int i=1;i<n;i++) 109 { 110 scanf("%d%d%d",&x,&y,&d); 111 ins(x,y,d); 112 ins(y,x,d); 113 } 114 // for(int i=1;i<=len;i++) 115 // printf("%d --> %d\n",a[i].x,a[i].y); 116 dfs(1,0); 117 lca_init(); 118 int l=0,r=0,mid; 119 for(int i=1;i<=m;i++) 120 { 121 scanf("%d%d",&q[i].x,&q[i].y); 122 q[i].z=lca_query(q[i].x,q[i].y); 123 q[i].d=dis[q[i].x]+dis[q[i].y]-2*dis[q[i].z]; 124 r=maxx(r,q[i].d); 125 } 126 while(l<r) 127 { 128 mid=(l+r)/2; 129 if(check(mid)) r=mid; 130 else l=mid+1; 131 } 132 printf("%d\n",l); 133 return 0; 134 }