2019 国防科技大学校赛
解题过程
开场发现J是水题,lfw写J过了,然后shl告诉lfwA题题意,lfw开始写A,中间又有人过了I,shl告诉lfw和byf I题意,但是沟通出现了问题,lfw没有准确把握I题的题意,继续写A,shl和byf讨论I题,后来lfw又加入讨论,弄清楚了I题的题意,一起讨论出了I题怎么写,lfw让byf想I题的写法,然后继续写A题。A题WA了,lfw叫shl过来看代码,但是shl和lfw都没有发现问题, byf开始写I,lfw和shl继续看题,讨论了一下很多人做的C题,还有看上去不太可做的D题,但是没有什么想法,byf A 掉 I 以后,lfw继续上机找A题的错误,此时byf发现了G题,大家一起讨论了一下,lfw提出高度只能是0和1,然后byf瞬间反应过来是平面图转对偶图,lfw不会,于是和shl开始讨论,shl上机写题,此时发现有人过E题,byf跟lfw开始讨论,但是lfw一开始又没有听懂byf表述的题意,花了好长时间弄清楚题意后,想出了分组背包,此时shl还在写G,中间发现memset不能设置为inf,shl不了解memset参数的意思,lfw和byf让shl直接用for循环,lfw继续看题,发现很多人过了H,而H题似乎可以扫描线做。shl交G题以后WA了,开始和byf一起查错,查错再交未果,lfw开始上机写E,E题写了一半lfw开始想不清楚dp数组定义的状态,于是下机给shl和byf继续修改G题的代码,然后lfw想清楚后,上机写E并ac了,最后byf和shl再次修改G的代码继续提交,坐在前面的出题人回头跟我们说你们的做法是对的,肯定是小细节出错了,但是还是WA。最后lfw上机找A题的错误,虽然中间有几次开始聊天划水不想找错误了,不过还是觉得不能放弃继续找错,于是在最后7,8分钟的时候发现A题循环时的漏洞,和对于不能逃出的人输出-1,而不是有人不能逃出就直接输出-1的低级输出错误。
赛后发现是纸质题面的输入写错了,所以G WA了,如果G没有查错那么久,甚至还可以再做出H题。运气不好。
题解
https://blog.csdn.net/liufengwei1/article/details/90053775
1 #include<bits/stdc++.h> 2 #define maxl 1010 3 using namespace std; 4 5 int n,m,p; 6 int tx[5]={0,1,0,-1,0}; 7 int ty[5]={0,0,1,0,-1}; 8 int ans[maxl*maxl]; 9 int dis[maxl][maxl]; 10 struct peo 11 { 12 int x,y,w; 13 }a[maxl*maxl]; 14 struct que 15 { 16 int id,tm; 17 }; 18 vector <que> ext[maxl][maxl]; 19 struct pr 20 { 21 int x,y; 22 bool operator < (const pr &b)const 23 { 24 if(x==b.x) 25 return y<b.y; 26 return x<b.x; 27 } 28 }outto[maxl][maxl]; 29 char ch[maxl][maxl]; 30 queue <pr> q; 31 priority_queue <pr> priq; 32 33 inline void prework() 34 { 35 for(int i=1;i<=n;i++) 36 scanf("%s",ch[i]+1); 37 for(int i=1;i<=p;i++) 38 { 39 scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w); 40 ans[i]=-1; 41 } 42 for(int i=1;i<=n;i++) 43 for(int j=1;j<=m;j++) 44 ext[i][j].clear(); 45 } 46 47 inline bool cmp(const que &x,const que &y) 48 { 49 if(x.tm==y.tm) 50 { 51 return a[x.id].w>a[y.id].w; 52 } 53 return x.tm<y.tm; 54 } 55 56 inline void mainwork() 57 { 58 while(!q.empty()) q.pop(); 59 memset(dis,0x3f,sizeof(dis)); 60 for(int i=1;i<=n;i++) 61 for(int j=1;j<=m;j++) 62 if(ch[i][j]=='2') 63 { 64 q.push(pr{i,j}); 65 outto[i][j]=pr{i,j}; 66 dis[i][j]=0; 67 } 68 pr u;int xx,yy; 69 while(!q.empty()) 70 { 71 u=q.front();q.pop(); 72 for(int i=1;i<=4;i++) 73 { 74 xx=u.x+tx[i];yy=u.y+ty[i]; 75 if(xx>=1 && xx<=n && yy>=1 && yy<=m && ch[xx][yy]!='1') 76 { 77 if(dis[xx][yy]>dis[u.x][u.y]+1) 78 { 79 dis[xx][yy]=dis[u.x][u.y]+1; 80 outto[xx][yy]=outto[u.x][u.y]; 81 q.push(pr{xx,yy}); 82 } 83 } 84 } 85 } 86 int tm; 87 for(int i=1;i<=p;i++) 88 if(dis[a[i].x][a[i].y]<dis[0][0]) 89 { 90 u=outto[a[i].x][a[i].y]; 91 tm=dis[a[i].x][a[i].y]; 92 ext[u.x][u.y].push_back(que{i,tm}); 93 } 94 int l,k; 95 for(int i=1;i<=n;i++) 96 for(int j=1;j<=m;j++) 97 { 98 l=ext[i][j].size(); 99 if(l==0) continue; 100 sort(ext[i][j].begin(),ext[i][j].end(),cmp); 101 k=0; 102 tm=0; 103 while(!priq.empty()) priq.pop(); 104 do 105 { 106 if(k<l && ext[i][j][k].tm>tm && priq.empty()) 107 tm=ext[i][j][k].tm; 108 while(k<l && ext[i][j][k].tm==tm) 109 { 110 priq.push(pr{a[ext[i][j][k].id].w,ext[i][j][k].id}); 111 k++; 112 } 113 u=priq.top();priq.pop(); 114 ans[u.y]=tm; 115 tm++; 116 }while(k<l || !priq.empty()); 117 } 118 } 119 120 inline void print() 121 { 122 for(int i=1;i<=p;i++) 123 printf("%d%c",ans[i],(i==p)?'\n':' '); 124 } 125 126 int main() 127 { 128 while(~scanf("%d%d%d",&n,&m,&p)) 129 { 130 prework(); 131 mainwork(); 132 print(); 133 } 134 return 0; 135 }
E、Missile
https://blog.csdn.net/liufengwei1/article/details/90054130
#include<bits/stdc++.h> #define maxl 510 using namespace std; int n,m,num; int a[maxl],w[maxl],c[maxl],f[maxl*maxl]; double r[maxl]; struct node { int w,c; }; vector <node> q[maxl]; bool flag; inline int rnd(double x) { return (int)(x+0.5); } inline void prework() { num=0; for(int i=1;i<=n;i++) scanf("%d",&w[i]),num+=w[i]; for(int i=1;i<=n;i++) scanf("%d",&c[i]); for(int i=1;i<=n;i++) scanf("%lf",&r[i]); for(int i=1;i<=n;i++) q[i].clear(); int ww,neww,t;double sum,tmp; for(int i=1;i<=n;i++) { tmp=1;sum=r[i];t=1; ww=rnd(sum*w[i]); q[i].push_back(node{ww,t*c[i]}); tmp=tmp*(1.0-r[i]); while(ww<w[i]) { sum=sum+tmp*r[i];t++; neww=rnd(sum*w[i]); if(neww!=ww) { ww=neww; q[i].push_back(node{ww,t*c[i]}); } tmp=tmp*(1-r[i]); } } } inline void mainwork() { for(int i=1;i<=num+1;i++) f[i]=2e9; f[0]=0; int l; for(int i=1;i<=n;i++) { l=q[i].size(); for(int j=num;j>=0;j--) { f[j]=min(f[j],f[j+1]); for(int k=0;k<l;k++) if((j-q[i][k].w)>=0) f[j]=min(f[j],f[j-q[i][k].w]+q[i][k].c); } } } inline void print() { int s; for(int i=1;i<=m;i++) { scanf("%d",&s); if(s>num || s<0 ) puts("Impossible"); else printf("%d\n",f[s]); } } int main() { while(~scanf("%d%d",&n,&m)) { prework(); mainwork(); print(); } return 0; }
G、Altitude
赛后改了输入顺序就过了
https://blog.csdn.net/baiyifeifei/article/details/89819395
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const ll INF=1ll<<60; 5 const int maxn=3e5+10; 6 7 struct Edge{ 8 int v,nxt; 9 ll w; 10 } edge[maxn<<2]; 11 int head[maxn],cnt; 12 ll dis[maxn]; 13 int n; 14 struct Node{ 15 int id; 16 ll w; 17 bool operator <(const Node &b) const {return w>b.w;} 18 }; 19 void Init() 20 { 21 memset(head,-1,sizeof(head)); 22 cnt=0; 23 } 24 void addedge(int u,int v,ll w) 25 { 26 edge[cnt].v=v; 27 edge[cnt].w=w; 28 edge[cnt].nxt=head[u]; 29 head[u]=cnt++; 30 } 31 void Dij(int s) 32 { 33 for(int i=0;i<=n*n+1;++i) dis[i]=INF; 34 dis[s]=0; 35 priority_queue<Node> q; 36 q.push(Node{s,0}); 37 while(!q.empty()) 38 { 39 Node u=q.top();q.pop(); 40 int Id=u.id; 41 if(dis[Id]!=u.w) continue; 42 for(int i=head[Id];~i;i=edge[i].nxt) 43 { 44 int v=edge[i].v; 45 if(dis[v]>dis[Id]+edge[i].w) 46 { 47 dis[v]=dis[Id]+edge[i].w; 48 q.push(Node{v,dis[v]}); 49 } 50 } 51 } 52 } 53 54 int main() 55 { 56 while(~scanf("%d",&n)) 57 { 58 Init(); 59 int s=0,t=n*n+1; 60 ll val; 61 // w-->e 62 for(int i=1;i<=n;++i) scanf("%lld",&val),addedge(i,t,val); 63 for(int i=1;i<=n*(n-1);++i) 64 { 65 scanf("%lld",&val); 66 //addedge(i,i+n,val); 67 addedge(i+n,i,val); 68 } 69 for(int i=1;i<=n;++i) scanf("%lld",&val),addedge(s,n*(n-1)+i,val); 70 71 for(int i=1;i<=n;++i) 72 { 73 for(int j=0;j<=n;++j) 74 { 75 scanf("%lld",&val); 76 if(j==0){addedge(s,(i-1)*n+1,val);}//×ó²à 77 else if(j==n){addedge(i*n,t,val);}// you 78 else {addedge(j+n*(i-1),j+n*(i-1)+1,val);}// zhong 79 } 80 } 81 82 //e-->w 83 84 for(int i=1;i<=n;++i) scanf("%lld",&val),addedge(t,i,val); 85 for(int i=1;i<=n*(n-1);++i) 86 { 87 scanf("%lld",&val); 88 addedge(i,i+n,val); 89 //addedge(i+n,i,val); 90 } 91 for(int i=1;i<=n;++i) scanf("%lld",&val),addedge(n*(n-1)+i,s,val); 92 93 //s-->n 94 for(int i=1;i<=n;++i) 95 { 96 for(int j=0;j<=n;++j) 97 { 98 scanf("%lld",&val); 99 if(j==0){addedge((i-1)*n+1,s,val);}//×ó²à 100 else if(j==n){addedge(t,i*n,val);}// you 101 else {addedge(j+n*(i-1)+1,j+n*(i-1),val);}// zhong 102 } 103 } 104 // n-->s 105 106 107 //for(int i=1;i<=n*(n+1);++i) scanf("%d",&val); 108 Dij(s); 109 printf("%lld\n",dis[t]); 110 } 111 112 return 0; 113 }
赛后补的,直接判断每个点再多少个等高线内就行了。
1 #include<bits/stdc++.h> 2 #define maxl 310 3 #define eps 1e-8 4 using namespace std; 5 6 inline int sgn(double x) 7 { 8 if(x>-eps && x<eps) 9 return 0; 10 if(x>0) return 1; 11 else return -1; 12 } 13 14 struct point 15 { 16 double x,y; 17 point(double a=0,double b=0) 18 { 19 x=a;y=b; 20 } 21 point operator - (const point &b)const 22 { 23 return point(x-b.x,y-b.y); 24 } 25 }; 26 inline double det(point a,point b) 27 { 28 return a.x*b.y-a.y*b.x; 29 } 30 inline double dot(point a,point b) 31 { 32 return a.x*b.x+a.y*b.y; 33 } 34 struct line 35 { 36 point s,e; 37 line(point a=point(),point b=point()) 38 { 39 s=a;e=b; 40 } 41 } ; 42 43 inline bool point_on_seg(point p,line l) 44 { 45 return sgn(det(p-l.s,l.e-l.s))==0 && sgn(dot(p-l.s,p-l.e))<=0; 46 } 47 48 inline int point_in(point t,point a[],int n) 49 {//0 out 1 in 2 on 50 int num=0,d1,d2,k; 51 a[n+1]=a[1]; 52 for(int i=1;i<=n;i++) 53 { 54 if(point_on_seg(t,line(a[i],a[i+1]))) 55 return 2; 56 k=sgn(det(a[i+1]-a[i],t-a[i])); 57 d1=sgn(a[i].y-t.y); 58 d2=sgn(a[i+1].y-t.y); 59 if(k>0 && d1<=0 && d2>0)num++; 60 if(k<0 && d2<=0 && d1>0)num++; 61 } 62 return num%2!=0; 63 } 64 65 int n,k,h,q; 66 int len[maxl]; 67 point a[maxl][maxl]; 68 69 inline void prework() 70 { 71 scanf("%d%d%d",&n,&k,&h); 72 n++; 73 for(int i=1;i<=n;i++) 74 { 75 scanf("%d",&len[i]); 76 for(int j=1;j<=len[i];j++) 77 scanf("%lf%lf",&a[i][j].x,&a[i][j].y); 78 } 79 } 80 81 inline void mainwork() 82 { 83 point p; 84 scanf("%d",&q); 85 for(int i=1;i<=q;i++) 86 { 87 scanf("%lf%lf",&p.x,&p.y); 88 bool flag=false;int st,num=0; 89 for(int j=1;j<=n;j++) 90 { 91 st=point_in(p,a[j],len[j]); 92 if(st==2) 93 flag=true; 94 if(st==1) 95 num++; 96 } 97 int ans=h+(num-1)*k; 98 if(flag) 99 ans+=k; 100 else 101 ans+=k/2; 102 printf("%d\n",ans); 103 } 104 } 105 106 int main() 107 { 108 prework(); 109 mainwork(); 110 return 0; 111 }
I、Geodetic
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=205; 4 vector<int> G[maxn]; 5 int val[maxn];bool vis[maxn]; 6 int dep[maxn]; 7 queue<int> q; 8 stack<int> s; 9 int solve(int x,int y) 10 { 11 memset(vis,0,sizeof(vis)); 12 while(!q.empty()) q.pop(); 13 while(!s.empty()) s.pop(); 14 q.push(x); 15 int deps=1; 16 vis[x]=true; 17 while(!q.empty()) 18 { 19 int u=q.front(); 20 q.pop(); 21 dep[u]=deps; 22 for(int i=0;i<G[u].size();i++) 23 { 24 int v=G[u][i]; 25 if(vis[v]) continue; 26 vis[v]=true; 27 s.push(v); 28 } 29 if(q.empty()) 30 { 31 while(!s.empty()) {q.push(s.top());s.pop();} 32 deps++; 33 } 34 } 35 memset(vis,0,sizeof(vis)); 36 while(!q.empty()) q.pop(); 37 q.push(y); 38 int ans=0; 39 while(!q.empty()) 40 { 41 int u=q.front(); 42 q.pop(); 43 ans+=val[u]; 44 for(int i=0;i<G[u].size();i++) 45 { 46 int v=G[u][i]; 47 if(vis[v]) continue; 48 if(dep[v]==dep[u]-1) 49 { 50 vis[v]=true; 51 q.push(v); 52 } 53 } 54 } 55 return ans; 56 } 57 int main() 58 { 59 int n,m; 60 scanf("%d%d",&n,&m); 61 for(int i=1;i<=n;i++) 62 { 63 scanf("%d",&val[i]); 64 } 65 int u,v; 66 for(int i=1;i<=m;i++) 67 { 68 scanf("%d%d",&u,&v); 69 G[u].push_back(v); 70 G[v].push_back(u); 71 } 72 int q; 73 scanf("%d",&q); 74 while(q--) 75 { 76 scanf("%d%d",&u,&v); 77 printf("%d\n",solve(u,v)); 78 } 79 return 0; 80 }
1 #include<bits/stdc++.h> 2 #define maxl 1010 3 using namespace std; 4 5 int n; 6 bool flag; 7 int a[maxl]; 8 char s[maxl]; 9 10 inline void prework() 11 { 12 scanf("%s",s+1); 13 n=strlen(s+1); 14 } 15 16 inline void mainwork() 17 { 18 flag=true; 19 for(int i=1;i<=n;i++) 20 if(s[i]!='6' && s[i]!='8') 21 { 22 flag=false; 23 return; 24 } 25 int tmp=s[n]-'0'; 26 if(n>=1) 27 tmp+=(s[n-1]-'0')*10; 28 if(tmp%4!=0) 29 { 30 flag=false; 31 return; 32 } 33 tmp=0; 34 for(int i=1;i<=n;i++) 35 { 36 tmp=tmp*10+(s[i]-'0'); 37 tmp%=7; 38 } 39 if(tmp>0) 40 flag=false; 41 } 42 43 inline void print() 44 { 45 if(flag) 46 puts("YES"); 47 else 48 puts("NO"); 49 } 50 51 int main() 52 { 53 int t; 54 scanf("%d",&t); 55 for(int i=1;i<=t;i++) 56 { 57 prework(); 58 mainwork(); 59 print(); 60 } 61 return 0; 62 }