# XJOI CSP-S2 2019开放模拟训练题1 赛后总结

## 友好数对

#include<bits/stdc++.h>
int T,L,R;

int F(int x)
{
int Len=0;
while(x){x/=10;Len++;}
return Len;
}

int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&L,&R);
int Len=F(L),p=1,Ans=0;
for(int i=1;i<Len;i++)p*=10;
for(register int A=L;A<=R;A++)
{
int B=A;
while(1)
{
B=B/10+p*(B%10);
if(A<B&&B<=R)++Ans;
if(A==B)break;
}
}
printf("%d\n",Ans);
}
return 0;
}


## 路径数

#include<bits/stdc++.h>
const int SIZE=105,N_MAX=10005,M_MAX=80005,Mod=1000000009;
int n,G[SIZE][SIZE],P[SIZE][SIZE],R[N_MAX];
int OFFX[]={0,-1,0,0,1},OFFY[]={0,0,-1,1,0};
bool E(int X,int Y){return (X<1||Y<1||X>n||Y>n||X+Y>n+1)? 0 : 1;}

struct node
{
int pos,D;
bool operator <(const node &x)const
{
return D>x.D;
}
};
std::priority_queue<node>q;
bool mk[N_MAX];
int D[N_MAX],F[N_MAX];
void Dijkstra()
{
memset(D,0x3F,sizeof(D));
memset(F,0,sizeof(F));
memset(mk,0,sizeof(mk));
D[1]=R[1];
F[1]=1;
q.push((node){1,D[1]});
while(q.size())
{
int u=q.top().pos;
q.pop();
if(mk[u])continue;
mk[u]=1;
{
int v=to[i];
if(D[v]>D[u]+R[v])
{
D[v]=D[u]+R[v];
F[v]=F[u];
q.push((node){v,D[v]});
}
else if(D[v]==D[u]+R[v])
F[v]=(F[v]+F[u])%Mod;
}
}
}

int main()
{
while(1)
{
scanf("%d",&n);
if(n==0)break;
int Tim=0;
memset(P,0,sizeof(P));
for(int i=1;i<=n;i++)
for(int k=1;k<=n;k++)
{
scanf("%d",&G[i][k]);
P[i][k]=++Tim;
}
++Tim;
memset(R,0,sizeof(R));
for(int i=1;i<=n;i++)
for(int k=1;k+i<=n+1;k++)
{
if(k+i==n+1)R[P[i][k]]=G[i][k];
else R[P[i][k]]=G[i][k]+G[n-k+1][n-i+1];
}
Tot=0;
for(int i=1;i<=n;i++)
for(int k=1;k+i<=n+1;k++)
{
for(int p=1;p<=4;p++)
{
int Xs=i+OFFX[p];
int Ys=k+OFFY[p];
if(E(Xs,Ys))
}
if(k+i==n+1)
}
Dijkstra();
printf("%d\n",F[Tim]);
}
return 0;
}



## 选信封

#include<bits/stdc++.h>
const int SIZE=1500;
#define Random(x) (rand()%x+1)

int n,A[SIZE][5],B[SIZE][5],Tem[SIZE],Ans,now,Tot;

struct LCT
{
int F[SIZE],C[SIZE][2];
bool Tag[SIZE];
#define LC(x) C[x][0]
#define RC(x) C[x][1]
bool NRoot(int x){return LC(F[x])==x||RC(F[x])==x;}
void Rev(int x){std::swap(LC(x),RC(x));Tag[x]^=1;}
void push_down(int x){if(Tag[x]){if(LC(x))Rev(LC(x));if(RC(x))Rev(RC(x));Tag[x]=0;}}
void Rotate(int x)
{
int u=F[x],v=F[u],k=(RC(u)==x),w=C[x][k^1];
if(NRoot(u))C[v][RC(v)==u]=x;C[x][k^1]=u;C[u][k]=w;
if(w)F[w]=u;F[u]=x;F[x]=v;
}
void push(int x){if(NRoot(x))push(F[x]);push_down(x);}
void Splay(int x)
{
for(push(x);NRoot(x);Rotate(x))
if(NRoot(F[x]))Rotate((LC(F[x])==x)^(LC(F[F[x]])==F[x])?x:F[x]);
}
void Access(int u){for(int v=0;u;u=F[v=u])Splay(u),RC(u)=v;}
void MakeRoot(int x){Access(x);Splay(x);Rev(x);}
int Find(int x){Access(x);Splay(x);while(LC(x)){push_down(x);x=LC(x);}Splay(x);return x;}
void Split(int u,int v){MakeRoot(u);Access(v);Splay(v);}
void Cut(int u,int v){MakeRoot(u);if(Find(v)==u&&F[v]==u&&!LC(v))F[v]=RC(u)=0;}
}T;

void SA()
{
for(double Temperature=1000;Temperature>1e-14;Temperature*=0.99)
{
int p=Random(n),o=Random(2);
if(T.Find(A[p][o])!=T.Find(B[p][o]))
{
++now;
Ans=std::max(Ans,now);
}
else if(exp(((double)Ans-now)/Temperature)<(double)Random(RAND_MAX)/RAND_MAX)
{
T.Cut(A[p][o],B[p][o]);
}
}
}

int main()
{
srand(time(0));
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d%d%d",&A[i][1],&B[i][1],&A[i][2],&B[i][2]);
Tem[++Tot]=A[i][1];
Tem[++Tot]=B[i][1];
Tem[++Tot]=A[i][2];
Tem[++Tot]=B[i][2];
}
std::sort(Tem+1,Tem+1+Tot);
for(int i=1;i<=n;i++)
{
A[i][1]=std::lower_bound(Tem+1,Tem+1+Tot,A[i][1])-Tem;
B[i][1]=std::lower_bound(Tem+1,Tem+1+Tot,B[i][1])-Tem;
A[i][2]=std::lower_bound(Tem+1,Tem+1+Tot,A[i][2])-Tem;
B[i][2]=std::lower_bound(Tem+1,Tem+1+Tot,B[i][2])-Tem;
}
SA();
printf("%d",Ans);
return 0;
}


# 这个模拟退火很明显是错的,我也不知道为啥就A了😢.

posted @ 2019-11-04 21:05  TaylorSwift13  阅读(324)  评论(0编辑  收藏  举报