这次模拟赛真的,,卡常赛。
The solution of T1:
std是打表,,考场上sb想自己改进匈牙利然后wei了(好像匈牙利是错的。
大力剪枝搜索。代码不放了。
这是什么神仙D1T1,爆蛋T1,好像A了它或拿分的就几个人,,
The solution of T2:
题解是这么写的:和八皇后很像,八皇后是x+y和x-y来判重,这里就k1x+k2y来判重。
从各个点引出直线,带入原点检验方程即可。
注:
#include <cstdio> #include <map> #include <algorithm> using namespace std; const int N=11; map <long long,int> M[N]; map <long long,int> T; int n,m,i,j,k,q,tx,ty,s,num; int x[N],y[N],dx[N],dy[N]; bool pd; int gcd(int a,int b){return b==0?a:gcd(b,a%b);} int main() { freopen("laser.in","r",stdin); freopen("laser.out","w",stdout); scanf("%d",&n); for (i=1;i<=n;i++) { scanf("%d%d",&tx,&ty); if (tx<0) tx=-tx,ty=-ty; y[i]=-tx,x[i]=ty; tx=abs(y[i]),ty=abs(x[i]),k=gcd(tx,ty); y[i]=y[i]/k,x[i]=x[i]/k; for (j=1;j<i;j++) if ((x[i]==x[j]) && (y[i]==y[j])) { i--,n--; break; } } scanf("%d",&m); for (i=1;i<=m;i++) { scanf("%d%d",&tx,&ty); for (j=1;j<=n;j++) M[j][1LL*tx*x[j]+1LL*ty*y[j]]++; T[tx*(long long) (1e9+1)+ty]++; } scanf("%d",&q); for (i=1;i<=q;i++) { s=0; scanf("%d%d",&tx,&ty); for (j=1;j<=n;j++) s=s+M[j][1LL*tx*x[j]+1LL*ty*y[j]]; s=s-(n-1)*T[tx*(long long) (1e9+1)+ty]; printf("%d\n",s); } return 0; }
所以,我只拿了60分。神tmD1T2
The solution of T3:
剪枝细节,,一堆的。不过和D1T3难度低一点吧。
考虑用 SPFA
迭代计算到达每个点存活且残余的最大 HP。(请注意加粗字体,旁边的大佬ldl因此 100->90 )
考虑到 SPFA 本 身是一个广搜的过程,自然也可以类似广搜地统计最少时间。因此,直接跑 SPFA 即可。时间复杂度 O(EAns)。
Code:
#include <cstdio> #include <algorithm> using namespace std; int edge[500000],next[500000],dist[500000],first[200000]; int b[200000],d[200000],g[10000000],h[10000000],p[200000],r[200000]; int i,k,m,n,x,y,z,head,tail,sum_edge; int main() { freopen("game.in","r",stdin); freopen("game.out","w",stdout); scanf("%d%d%d",&n,&m,&k); for (i=1;i<=n;i++) scanf("%d",&r[i]); for (i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); sum_edge++,edge[sum_edge]=y,next[sum_edge]=first[x],dist[sum_edge]=z,first[x]=sum_edge; sum_edge++,edge[sum_edge]=x,next[sum_edge]=first[y],dist[sum_edge]=z,first[y]=sum_edge; } d[1]=p[1]=k; tail++,g[tail]=1,h[tail]=0; for (head=1;head<=tail;head++) { if (g[head]==n) { printf("%d\n",h[head]); return 0; } if (h[head]!=h[head-1]) for (i=head;i<=tail;i++) d[g[i]]=p[g[i]],b[g[i]]=0; for (i=first[g[head]];i!=0;i=next[i]) if ((d[g[head]]>dist[i]) && (min(d[g[head]]-dist[i]+r[edge[i]],k)>p[edge[i]])) { p[edge[i]]=min(d[g[head]]-dist[i]+r[edge[i]],k); if (! b[edge[i]]) tail++,g[tail]=edge[i],h[tail]=h[head]+1,b[edge[i]]=1; } } printf("-1\n"); return 0; }
这题我莫名从60/70 -> 30???
神tmT1T2