2012金华邀请赛

 

 

模拟赛链接

A 第一个水题

要知道units digit的意思  (个位数) 

有一点点小繁琐。

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<cmath>
  7 using namespace std;
  8 #define N 35
  9 int a[N],b[N];
 10 int o1[N],o2[N];
 11 struct node
 12 {
 13     int di;
 14     int v;
 15 }p[N];
 16 int judge(int x,int y,int n)
 17 {
 18     int i;
 19     for(i = 0 ;i < n ; i++)
 20     {
 21         int g = 0;
 22         while(x+g<=y&&o2[i+g]==o1[x+g])
 23         g++;
 24 //        if(x==1&&y==2)
 25 //        printf("%d, %d %d %d\n ",i,g,o2[i],o1[x]);
 26         if(x+g>y)
 27         return 1;
 28     }
 29     return 0;
 30 }
 31 bool cmp(node a,node b)
 32 {
 33     if(a.di==b.di)
 34     return a.v<b.v;
 35     return a.di<b.di;
 36 }
 37 bool ccmp(int a,int b)
 38 {
 39     return a>b;
 40 }
 41 int main()
 42 {
 43     int t,i,j,n1,n2;
 44     cin>>t;
 45     while(t--)
 46     {
 47         scanf("%d%d",&n1,&n2);
 48         for(i = 0;i < n1 ;i++)
 49         scanf("%d",&a[i]);
 50         for(i = 0 ;i< n2 ; i++)
 51         scanf("%d",&b[i]);
 52         sort(a,a+n1,ccmp); sort(b,b+n2,ccmp);
 53         int g1=1,g2=1,g;
 54         o1[0] = a[0];
 55         for(i = 1; i < n1 ; i++)
 56         if(a[i]!=a[i-1])
 57         {
 58             o1[g1++] = a[i];
 59         }
 60         o2[0] = b[0];
 61         for(i = 1;i < n2 ; i++)
 62         if(b[i]!=b[i-1])
 63         {
 64             o2[g2++] = b[i];
 65         }
 66         int st=-1,en=-1,mz=-1,maxz=-1;
 67         for(i = 0; i < g1 ; i++)
 68         {
 69             for(j = i ; j < g1 ; j++)
 70             {
 71                 if(judge(i,j,g2))
 72                 {
 73 //                    cout<<i<<" "<<j<<endl;
 74                     int mm = -1;
 75                     for(int e = i ; e <= j; e++)
 76                     mm = max(mm,o1[e]);
 77                     if(maxz<=j-i+1)
 78                     {
 79                         if(maxz<j-i+1||mm>mz)
 80                         {
 81                             st = i;
 82                             en = j;
 83                             mz = mm;
 84                             maxz = j-i+1;
 85                         }
 86                     }
 87                 }
 88             }
 89         }
 90         if(st==-1)
 91         {
 92             puts("NONE");
 93             continue;
 94         }
 95         g = 0;
 96         for(i = st ; i<= en; i++)
 97         {
 98             p[g].v = o1[i];
 99             p[g].di = o1[i]%10;
100             g++;
101         }
102         for(i = 0 ;i < g-1 ; i++)
103         printf("%d ",p[i].v);
104         printf("%d\n",p[i].v);
105         sort(p,p+g,cmp);
106         for(i = 0 ;i < g-1 ; i++)
107         printf("%d ",p[i].v);
108         printf("%d\n",p[i].v);
109     }
110     return 0;
111 }
View Code

 

队友过的,待填。。

C

卡时限的奇葩题。

预处理出以k点为最高价格点时到其它点的单源最短路径,在询问时用这个n种情况依次更新u,v;

minz = min(minz,w[k][u]+w[k][v]+p[k]);

直接写可能会超时,反正我超了N久,需要把询问先读进来,再依次更新。

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 1010
 12 #define M 20010
 13 #define LL long long
 14 #define INF 1e18
 15 const double eps = 1e-8;
 16 const double pi = acos(-1.0);
 17 const double inf = ~0u>>2;
 18 vector<int>ed[N][2];
 19 int cot[N],co[N][N];
 20 LL w[N][N],dis[N],mm[M];
 21 bool vis[N];
 22 struct node
 23 {
 24     int c,id;
 25 }p[N];
 26 struct nodd
 27 {
 28     int u,v;
 29 }qi[M];
 30 struct mode
 31 {
 32     int u;
 33     LL w;
 34     friend bool operator <(const mode &a,const mode &b)
 35     {
 36         return a.w>b.w;
 37     }
 38 };
 39 void spfa(int st,int n)
 40 {
 41     memset(vis,0,sizeof(vis));
 42     queue<mode>q;
 43     int i;
 44     mode tt,ts;
 45     for(i = 1; i <= n; i++)
 46     {
 47         dis[i] = INF;
 48     }
 49     ts.u = st;
 50     ts.w = 0;
 51     q.push(ts);
 52     vis[st] = 1;
 53     dis[st] = 0;
 54     while(!q.empty())
 55     {
 56         tt = q.front();
 57         int u = tt.u;
 58         q.pop();
 59         vis[u] = 0;
 60         for(i = 0 ;i  < ed[u][0].size(); i++)
 61         {
 62             int v = ed[u][0][i];
 63             int w = ed[u][1][i];
 64             if(p[v].c>p[st].c) continue;
 65             if(dis[v]>dis[u]+w)
 66             {
 67                 dis[v] = dis[u]+w;
 68                 if(!vis[v])
 69                 {
 70                     ts.u = v;
 71                     ts.w = dis[v];
 72                     vis[v] = 1;
 73                     q.push(ts);
 74                 }
 75             }
 76         }
 77     }
 78 }
 79 bool cmp(node a,node b)
 80 {
 81     return a.c>b.c;
 82 }
 83 int main()
 84 {
 85     int n,m,i,j;
 86     while(scanf("%d%d",&n,&m)&&n&&m)
 87     {
 88         for(i = 1; i <= n ; i++)
 89         {
 90             scanf("%d",&p[i].c);
 91             p[i].id = i;
 92             ed[i][0].clear();
 93             ed[i][1].clear();
 94         }
 95         for(i = 1; i <= m; i++)
 96         {
 97             int u,v,w;
 98             scanf("%d%d%d",&u,&v,&w);
 99             ed[u][0].push_back(v);
100             ed[u][1].push_back(w);
101             ed[v][0].push_back(u);
102             ed[v][1].push_back(w);
103         }
104         ;
105         int q;
106         scanf("%d",&q);
107         for(i = 1; i <= q ; i++)
108         {
109             scanf("%d%d",&qi[i].u,&qi[i].v);
110             mm[i] = INF;
111         }
112         for(i = 1 ;i <= n ; i++)
113         {
114             spfa(i,n);
115             for(j = 1; j <= q ; j++)
116             {
117                 mm[j] = min(mm[j],dis[qi[j].u]+dis[qi[j].v]+p[i].c);
118             }
119         }
120         for(i  = 1; i < q; i++)
121         {
122             if(mm[i]==INF)
123             printf("-1\n");
124             else
125             printf("%lld\n",mm[i]);
126         }
127         if(mm[q]==INF)
128         puts("-1");
129         else
130         printf("%lld\n",mm[q]);
131         puts("");
132     }
133     return 0;
134 }
View Code

 

D

线段树水题,有段时间没写,居然lz忘记更新,卡了几个小时。。。

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<cmath>
  7 using namespace std;
  8 #define N 200010
  9 #define INF 0xfffffff
 10 int a[N],b[N],lz[N<<2];
 11 int s[N<<2];
 12 void up(int w)
 13 {
 14     s[w] = max(s[w<<1],s[w<<1|1]);
 15 }
 16 void build(int l,int r,int w)
 17 {
 18     lz[w] = 0;
 19     if(l==r)
 20     {
 21         s[w] = a[l];
 22         return ;
 23     }
 24     int m = (l+r)>>1;
 25     build(l,m,w<<1);
 26     build(m+1,r,w<<1|1);
 27     up(w);
 28 }
 29 void down(int w,int m)
 30 {
 31     if(lz[w]!=0)
 32     {
 33         s[w<<1]+=lz[w];
 34         s[w<<1|1]+=lz[w];
 35         lz[w<<1]+=lz[w];
 36         lz[w<<1|1]+=lz[w];
 37         lz[w] = 0;
 38     }
 39 }
 40 void update(int x,int y,int d,int l,int r,int w)
 41 {
 42     if(x<=l&&y>=r)
 43     {
 44         s[w] += d;
 45         lz[w] += d;
 46         return ;
 47     }
 48     down(w,r-l+1);
 49     int m = (l+r)>>1;
 50     if(x<=m)
 51     update(x,y,d,l,m,w<<1);
 52     if(y>m)
 53     update(x,y,d,m+1,r,w<<1|1);
 54     up(w);
 55 }
 56 int query(int x,int y,int l,int r,int w)
 57 {
 58     if(x<=l&&y>=r)
 59     return s[w];
 60     int m  =(l+r)>>1;
 61     down(w,r-l+1);
 62     int res = -INF;
 63     if(x<=m)
 64     res = max(query(x,y,l,m,w<<1),res);
 65     if(y>m)
 66     res = max(query(x,y,m+1,r,w<<1|1),res);
 67     return res;
 68 }
 69 int main()
 70 {
 71     int i,n,t,m,k;
 72     scanf("%d",&t);
 73     while(t--)
 74     {
 75         scanf("%d%d%d",&n,&m,&k);
 76         for(i = 1 ;i <= n; i++)
 77             scanf("%d",&b[i]);
 78         a[n+1] = 0;
 79         int g = n;
 80         for(i = n ; i >= 1 ; i--)
 81         {
 82             a[i] = a[i+1]+b[i];
 83             if(n-i+1>k)
 84             {
 85                 a[i]-=b[g--];
 86             }
 87         }
 88         n = n-k+1;
 89         build(1,n,1);
 90         while(m--)
 91         {
 92             int x,y,z;
 93             scanf("%d%d%d",&z,&x,&y);
 94             if(z==0)
 95             {
 96                 update(max(x-k+1,1),min(x,n),y-b[x],1,n,1);
 97                 b[x] = y;
 98             }
 99             else if(z==1)
100             {
101                 update(max(x-k+1,1),min(x,n),b[y]-b[x],1,n,1);
102                 update(max(y-k+1,1),min(y,n),b[x]-b[y],1,n,1);
103                 swap(b[x],b[y]);
104             }
105             else
106             printf("%d\n",query(x,y-k+1,1,n,1));
107         }
108     }
109     return 0;
110 }
View Code

 

E

简单几何题,枚举所在点到所有线段端点的直线,可以想到最多穿墙的线肯定是过端点的。

注意一点,给出的线段会有与你枚举的直线重合的线段

  1 #include <iostream>
  2 #include <algorithm>
  3 #include <cmath>
  4 #include <cstring>
  5 #include <string>
  6 #include <cstdio>
  7 using namespace std;
  8 #define eps 1e-8
  9 #define zero(x) (((x)>0?(x):-(x)) < eps)
 10 struct point
 11 {
 12     double x,y;
 13 }p[4001];
 14 struct line
 15 {
 16     point a,b;
 17 };
 18 double dis(point p1,point p2)
 19 {
 20     return (p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y);
 21 }
 22 double xmult(point p1,point p2,point p0)
 23 {
 24     return (p1.x-p0.x)*(p2.y-p0.y) - (p2.x-p0.x)*(p1.y-p0.y);
 25 }
 26 int pinline(point p,line l)
 27 {
 28     return zero(xmult(p,l.a,l.b))&&(l.a.x-p.x)*(l.b.x-p.x) < eps&&(l.a.y-p.y)*(l.b.y-p.y) < eps;
 29 }
 30 point inter(point u1,point u2,point v1,point v2)
 31 {
 32     point ret = u1;
 33     double t = ((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))
 34                 /((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
 35     ret.x += (u2.x-u1.x)*t;
 36     ret.y += (u2.y-u1.y)*t;
 37     return ret;
 38 }
 39 int pingxing(line u,line v)
 40 {
 41     return zero((u.a.x-u.b.x)*(v.a.y-v.b.y)-(v.a.x-v.b.x)*(u.a.y-u.b.y));
 42 }
 43 int nopoint(point p,line l)
 44 {
 45     return pinline(p,l)&&(!zero(p.x-l.a.x)||!zero(p.y-l.a.y))&&(!zero(p.x-l.b.x)||!zero(p.y-l.b.y));
 46 }
 47 int main()
 48 {
 49     int n,t,i,j,ans,num;
 50     scanf("%d",&t);
 51     while(t--)
 52     {
 53         scanf("%d",&n);
 54         for(i = 1;i <= 2*n;i ++)
 55         {
 56             scanf("%lf%lf",&p[i].x,&p[i].y);
 57         }
 58         ans = 0;
 59         scanf("%lf%lf",&p[0].x,&p[0].y);
 60         for(i = 1;i <= 2*n;i ++)
 61         {
 62             num = 0;
 63             for(j = 1;j <= n;j ++)
 64             {
 65                 line u,v,ti;
 66                 point temp;
 67                 u.a = p[0];
 68                 u.b = p[i];
 69                 v.a = p[2*j-1];
 70                 v.b = p[2*j];
 71                 ti.a = p[0];
 72                 ti.b = p[i];
 73                 if(pinline(p[2*j],ti))
 74                 {
 75                     num++;
 76                     continue;
 77                 }
 78                 ti.b = p[2*j];
 79                 if(pinline(p[i],ti))
 80                 {
 81                     num++;
 82                     continue;
 83                 }
 84                 if(pingxing(u,v)) continue;
 85                 temp = inter(p[0],p[i],p[2*j-1],p[2*j]);
 86                 if(pinline(temp,v))
 87                 {
 88                     line tt;
 89                     tt.a = p[0];
 90                     tt.b = temp;
 91                     if(pinline(p[i],tt))
 92                     num ++;
 93                     else
 94                     {
 95                         tt.a = p[0];
 96                         tt.b = p[i];
 97                         if(pinline(temp,tt))
 98                         num++;
 99                     }
100                 }
101             }
102             ans = max(ans,num);
103         }
104         printf("%d\n",ans);
105     }
106     return 0;
107 }
View Code

 

H

ac自动机,比赛的时候没来得及看,看了也不一定会。。

这个题不管 去除子串这个条件就是裸自动机,可以先进行裸自动机把需要的串标记出来,再在已经标记的串里面进行自动机的查找去掉它所含有的子串。

因为数据挺大,可以省掉strlen()这个操作,全改为指针操作。

模板里面有句话错了,wa了N久。。

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 3100010
 12 #define M 1100
 13 #define NN 5100000
 14 #define LL long long
 15 #define INF 0xfffffff
 16 const double eps = 1e-8;
 17 const double pi = acos(-1.0);
 18 const double inf = ~0u>>2;
 19 const int child_num = 26;
 20 bool o[2510];
 21 char s[NN],sr[NN],vir[M];
 22 char dig[20],ss[2510][M];
 23 class ACAutomo
 24 {
 25 private:
 26     int ch[N][child_num];
 27     int val[N];
 28     int fail[N];
 29     int Q[N];
 30     int id[128];
 31     int sz;
 32 public:
 33     void init()
 34     {
 35         fail[0] = 0;
 36         for(int i = 'A'; i <= 'Z' ; i++)
 37             id[i] = i-'A';
 38     }
 39     void reset()
 40     {
 41         memset(ch[0],0,sizeof(ch[0]));
 42         memset(o,0,sizeof(o));
 43         sz = 1;
 44     }
 45     void insert(char *a,int key)
 46     {
 47         int p = 0 ;
 48         for( ; *a !='\0'; a++)
 49         {
 50             int d = id[*a];
 51             if(ch[p][d]==0)
 52             {
 53                 memset(ch[sz],0,sizeof(ch[sz]));
 54                 val[sz] = 0;
 55                 ch[p][d] = sz++;
 56             }
 57             p = ch[p][d];
 58         }
 59         val[p]=key;
 60     }
 61     void construct()
 62     {
 63         int i,head=0,tail = 0;
 64         for(i = 0 ; i < child_num ; i++)
 65         {
 66             if(ch[0][i])
 67             {
 68                 Q[tail++] = ch[0][i];
 69                 fail[ch[0][i]] = 0;
 70             }
 71         }
 72         while(head!=tail)
 73         {
 74             int u = Q[head++];
 75             for(i = 0; i < child_num ; i++)
 76             {
 77                 if(ch[u][i])
 78                 {
 79                     Q[tail++] = ch[u][i];
 80                     fail[ch[u][i]] = ch[fail[u]][i];
 81                 }
 82                 else
 83                     ch[u][i] = ch[fail[u]][i];
 84             }
 85         }
 86     }
 87     void work(char *s)
 88     {
 89         int p = 0;
 90         for( ; *s!='\0' ; s++)
 91         {
 92             int d = id[*s];
 93             p = ch[p][d];
 94             int tmp = p;
 95             if(val[tmp])
 96             {
 97                 o[val[tmp]] = 1;
 98                 continue;
 99             }
100             while(tmp!=0&&val[tmp]!=0)
101             {
102                 o[val[tmp]] = 1;
103                 tmp = fail[tmp];
104             }
105         }
106     }
107     void solve(char *s)
108     {
109         int p = 0;
110         for( ; *s!='\0' ; s++)
111         {
112             int d = id[*s];
113             p = ch[p][d];
114             int tmp = p;
115             while(tmp!=0&&val[tmp]!=0)
116             {
117                 o[val[tmp]] = 0;
118                 tmp = fail[tmp];
119             }
120         }
121     }
122 } ac;
123 void change(char *sr,int k)
124 {
125     int g=0;
126     for( ; *sr!='\0' ; sr++)
127     {
128         if((*sr)>='A'&&(*sr)<='Z')
129         {
130             if(k!=-1)
131                 ss[k][g++] = (*sr);
132             else
133                 s[g++] = (*sr);
134         }
135         else if((*sr)=='[')
136         {
137             sr++;
138             int e = 0;
139             while((*sr)>='0'&&(*sr)<='9')
140             {
141                 dig[e++] = (*sr);
142                 sr++;
143             }
144             dig[e] = '\0';
145             int num = atoi(dig);
146             while(num--)
147             {
148                 if(k!=-1)
149                     ss[k][g++] = (*sr);
150                 else
151                     s[g++] = (*sr);
152             }
153             sr++;
154         }
155     }
156     if(k!=-1)
157         ss[k][g] = '\0';
158     else
159         s[g] = '\0';
160 }
161 int main()
162 {
163     int n,i;
164     ac.init();
165     int t;
166     scanf("%d",&t);
167     int tt = 0;
168     while(t--)
169     {
170         tt++;
171         scanf("%d",&n);
172         ac.reset();
173         for(i = 1; i <= n; i++)
174         {
175             scanf("%s",vir);
176             change(vir,i);
177             ac.insert(ss[i],i);
178         }
179         //cout<<n<<endl;
180         ac.construct();
181         scanf("%s",sr);
182 //        if(tt>12)
183 //        {
184 //            puts("1");
185 //            continue;
186 //        }
187         change(sr,-1);
188         ac.work(s);
189         for(i = 1 ; i <= n ; i++)
190         {
191             if(o[i])
192             {
193                 ac.solve(ss[i]);
194                 o[i] = 1;
195             }
196         }
197         int num = 0;
198         for(i = 1; i <= n; i++)
199             if(o[i]) num++;
200         printf("%d\n",num);
201     }
202     return 0;
203 }
View Code

 

 

 

posted @ 2014-07-07 17:07  _雨  阅读(264)  评论(2编辑  收藏  举报