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 }

 

posted @ 2016-11-17 16:40  拦路雨偏似雪花  阅读(478)  评论(0编辑  收藏  举报