题目并不难只要注意分析一下题目的牌的摆放的方法即可,观察后发现按照题目给的规则进行摆放就会所有牌首尾相连形成一些链或一些环,这样就有的属于某个环或链,或者不属于这个环或链的逻辑关系,很容易就想到了并查集来实现。或者想不到也没关系,你可以去按照链或环的思维继续的想下去,无非就是要找出链或环的长度,这样就可以去搜索了找长度了,链或环的长度都知道了怎样选择去牌也就显而易见了
下面的代码使用的是并查集比较直接的一种方式,一可以采用另外的一种并查集,可以直接统计集合内元素个数的那种,那种并查集是0ms我代码的是31ms,慢了一点
其实这题有很多人是用二分图做的
#include<cstdio> #include<cstring> int m,n,p[105*105],num[105*105],i,a,b,x,y; int findp(int x) { return x==p[x]?x:p[x]=findp(p[x]); } int read() { scanf("%d%d",&m,&n); if(!(m+n)) return 0; memset(num,0,sizeof(num)); for( i=0;i<102*102;i++) p[i]=i; for(i=0;i<m;i++) { scanf("%d%d",&a,&b); x=findp(a*102+b),y=findp((a+1)*102+b); if(x!=y) p[x]=y; } for( i=0;i<n;i++) { scanf("%d%d",&a,&b); x=findp(a*102+b),y=findp(a*102+b+1); if(x!=y) p[x]=y; } return 1; } void deal() { int ans=0; for( i=0;i<102*102;i++) num[findp(i)]++; for(i=0;i<102*102;i++) ans+=(num[i]/2); printf("%d\n",ans); } int main() { while(read()) deal(); return 0; }