标签:网格 ace blank sub 整数 ++ das sample content
7
1 1
1 1
1 1
1 2
1 3
2 2
3 1
在一个5000*5000的矩阵里,已知n对(x,y),表示在(x,y)有一个雷神标记,若Xa==Xb并且Ya==Yc则(Xc,Yb)处也会产生一个雷神标记,最后他有一定限制的走,问最大的长或宽是多少
然后把所有点的坐标都列出来(1,5001)(1,5002)(2,5002)----->(2,5001),仔细一数好像每个数字都出现了俩次,然后如果把每个给定点的坐标都放到一个集合里就可以发现有这么一个集合{1,5001,2,5002},然后把集合里的数排列一下,小于5000的当X,大于5000的当Y,会发现有四个坐标,其中三个是我们已知的,而另外一个就是我扩展出来的点的坐标。
再举个栗子
对于上面这个图,可以形成{2,5001}和{1,5002,3}两个集合,然而拆开之后就会发现最多只会形成3个点,没有新的点就意味着没有可以扩展出来的新点。
1 #include<bits/stdc++.h> 2 using namespace std; 3 inline int read() 4 { 5 int x=0,f=1;char c=getchar(); 6 for(;!isdigit(c);c=getchar()) if(c==‘-‘) f=-1; 7 for(;isdigit(c);c=getchar()) x=x*10+c-‘0‘; 8 return x*f; 9 } 10 const int maxn=5000; 11 int parents[maxn*2+50],f[maxn+50][maxn+50]; 12 inline int find(int x) {return parents[x]==x?x:parents[x]=find(parents[x]);} 13 int main() 14 { 15 int n=read(); 16 for(int i=1;i<=10000;i++) parents[i]=i; 17 for(int i=1;i<=n;i++) 18 { 19 int x=read(),y=read(); 20 parents[find(x)]=find(y+maxn); 21 } 22 for(int i=1;i<=maxn;i++) 23 { 24 for(int j=1;j<=maxn;j++) 25 { 26 if(find(i)==find(j+maxn)) 27 { 28 f[i][j]=f[i-1][j-1]+1; 29 } 30 else 31 { 32 f[i][j]=max(f[i][j-1],f[i-1][j]); 33 } 34 35 } 36 } 37 printf("%d\n",f[maxn][maxn]); 38 return 0; 39 }
标签:网格 ace blank sub 整数 ++ das sample content
原文地址:https://www.cnblogs.com/2529102757ab/p/11444214.html