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 }
B
队友过的,待填。。
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 }
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 }
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 }
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 }