其实本题是加强版,原数据是100*100的,老师为了尊重我们的智商加成了3000*3000并进行了字符串处理……
上原题~
球迷
【问题描述】
一个球场C的球迷看台可容纳M*N个球迷。官方想统计一共有多少球迷群体,最大的球迷群体有多少人。
球迷选座特性:同球迷群体会选择相邻座位,不同球迷群体选择不相邻的座位。(相邻包括前后相邻、左右相邻、斜对角相邻);
给定一个M*N的二位球场,0代表该位置没人,1代表该位置有人,希望输出球队群体个数P,最大的球队群体人数Q。
【输入】
第一行,2个数字,M、N,使用英文逗号隔开。
接下来M行,每行N个数字,使用英文逗号隔开。
【输出】
一行,2数字,P和Q。
【输入输出样例】
fans.in |
fans.out |
10,10 0,0,0,0,0,0,0,0,0,0 0,0,0,1,1,0,1,0,0,0 0,1,0,0,0,0,0,1,0,1 1,0,0,0,0,0,0,0,1,1 0,0,0,1,1,1,0,0,0,1 0,0,0,0,0,0,1,0,1,1 0,1,1,0,0,0,0,0,0,0 0,0,0,1,0,1,0,0,0,0 0,0,1,0,0,1,0,0,0,0 0,1,0,0,0,0,0,0,0,0 |
6,8 |
【数据范围】
对于100%的数据,1<=M,N<=3×103。
思路:特殊特判读入,找到有人就进行八连块搜索。
上代码~
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 using namespace std; 6 int m=0,n=0,t=0,num,maxnum=0; 7 bool fans[3010][3010]; 8 char x[10010]; 9 void reads()//字符串特判读入 10 { 11 scanf("%s",&x); 12 int l=strlen(x); 13 int i=0; 14 while(x[i]!=',') 15 {m=m*10+x[i]-48;i++;}//字符转数字 16 i++; 17 while(i<l) 18 {n=n*10+x[i]-48;i++;} 19 return; 20 } 21 void readings() 22 { 23 int l=n*2-1;//加上逗号的长度 24 for(int i=1;i<=m;i++) 25 { 26 scanf("%s",x); 27 for(int j=0;j<l;j=j+2) 28 fans[i][j/2+1]=x[j]-48;//由于是单个字符就不用累加了 29 } 30 return; 31 } 32 void dfs(int a,int b)//搜索 33 { 34 if(a<1||a>m||b<1||b>n) return;//越界判断 35 if(!fans[a][b]) return;//是否坐了人 36 fans[a][b]=0;//该人已经计数并撤去标记以免重复标记 37 num++; 38 dfs(a-1,b-1);//向八连块方向搜索坐在一起的球迷 39 dfs(a-1,b); 40 dfs(a-1,b+1); 41 dfs(a,b-1); 42 dfs(a,b); 43 dfs(a,b+1); 44 dfs(a+1,b-1); 45 dfs(a+1,b); 46 dfs(a+1,b+1); 47 return;//记得搜索完后退出去 48 } 49 int main() 50 { 51 reads();//特殊读入m和n 52 readings();//读入球迷就座情况 53 for(int i=1;i<=m;i++) 54 { 55 for(int j=1;j<=n;j++) 56 { 57 if(fans[i][j]) 58 { 59 t++;//发现一个单独的团体组织 60 num=0;//单个团体计数 61 dfs(i,j); 62 if(num>maxnum) maxnum=num;//更新最大值 63 } 64 } 65 } 66 printf("%d,%d",t,maxnum);//按要求输出 67 return 0; 68 }