$NOIP2015$ 题解报告
目录
$Luogu P2615$ 神奇的幻方$( √ )$
$Luogu P2661$ 信息传递$( √ )$
$Luogu P2668$ 斗地主$( √ )$
$Luogu P2678$ 跳石头$( √ )$
$Luogu P2679$ 子串$( √ )$
$Luogu P2680$ 运输计划$( √ )$
$Luogu P2615$ 神奇的幻方
昂直接模拟就好了
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n; 4 int square[40][40]; 5 struct Num{ 6 int x,y; 7 }num[40*40]; 8 void work(int k){ 9 if(num[k-1].x==1&&num[k-1].y!=n) 10 num[k].x=n,num[k].y=num[k-1].y+1; 11 if(num[k-1].y==n&&num[k-1].x!=1) 12 num[k].x=num[k-1].x-1,num[k].y=1; 13 if(num[k-1].x==1&&num[k-1].y==n) 14 num[k].x=2,num[k].y=num[k-1].y; 15 if(num[k-1].x!=1&&num[k-1].y!=n){ 16 if(square[num[k-1].x-1][num[k-1].y+1]==0) 17 num[k].x=num[k-1].x-1,num[k].y=num[k-1].y+1; 18 else 19 num[k].x=num[k-1].x+1,num[k].y=num[k-1].y; 20 } 21 square[num[k].x][num[k].y]=k; 22 return; 23 } 24 int main(){ 25 cin>>n; 26 square[1][n/2+1]=1; 27 num[1].x=1; 28 num[1].y=n/2+1; 29 for(int i=2;i<=n*n;i++) 30 work(i); 31 for(int i=1;i<=n;i++){ 32 for(int j=1;j<=n;j++) 33 cout<<square[i][j]<<" "; 34 cout<<endl; 35 } 36 }
$Luogu P2661$ 信息传递
并查集求最小环,如果两个点在一个集合里,那么就构成一个环,长度为两个点到这个集合的父亲节点的距离加上$1$
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=200002; 4 int n,fa[N],dis[N],minn; 5 int find(int x){ 6 if(fa[x]!=x){ 7 int last=fa[x]; 8 fa[x]=find(fa[x]); 9 dis[x]+=dis[last]; 10 } 11 return fa[x]; 12 } 13 void check(int x,int y){ 14 int fx=find(x),fy=find(y); 15 if(fx!=fy) {fa[fx]=fy;dis[x]=dis[y]+1;} 16 else minn=min(minn,dis[x]+dis[y]+1); 17 return; 18 } 19 int main(){ 20 int i,T; 21 scanf("%d",&n); 22 for(i=1;i<=n;i++) 23 fa[i]=i; 24 minn=N*2; 25 for(i=1;i<=n;i++){ 26 scanf("%d",&T); 27 check(i,T); 28 } 29 printf("%d",minn); 30 return 0; 31 }