7-9 排座位
这一题是典型的并查集的模板题,当然还可以用并查集来做,可以用二维数组来存储其中的关系。
并查集的模板:
int init(){
	for(int i=1;i<105;i++){
		father[i]=i;
	}
}
int findfather(int x){
	if(x==father[x]){
		return x;
	}else{
		return father[x]=findfather(father[x]);
	}
}
void unionfather(int a,int b){
	int fa=findfather(a);
	int fb=findfather(b);
	if(fa!=fb){
		father[fa]=fb;
	}
}
还有就是这个题在输入数据的时候,我们用二维数组book[][]来存储两者的关系,当两者是敌人的时候,为true,注意,敌人关系是相互的。
7-10 最长对称子串
这一题比较费脑子,例如他给出“Is PAT&TAP symmetric?”,需要你算出最长对称字串——“s PAT&TAP s”,这个的长度是11。
通过常识我们知道,对称串有两种情况,一种是对称串的长度为奇数,另一从为偶数,而这两者的区别就是对称的中心点不一样,奇数长度的是以一个字符为中心,偶数长度的是在两个字符中间为中心,抓住这一点就可以分类讨论了:
遍历字符串中每一个字符,针对每一个字符我们都做以上两种的分类的讨论,
核心代码如下:
for(int i=0;i<str.length();i++){
		len=1;/*原本就有一个*/ 
		for(int j=1;j<str.length();j++){/*如果所求串为奇数个字符*/
			if(i-j<0||i+j>=str.length()||str[i-j]!=str[i+j]){
				break;
			}else{
				len=len+2; 
			}
		}
		max_len=max(len,max_len);
		len=0;/*原本没有一个*/
		for(int j=1;j<str.length();j++){/*如果所求串为偶数个字符*/
			if(i-j+1<0||i+j>=str.length()||str[i-j+1]!=str[i+j]){
				break;
			}else{
				len=len+2;
			} 
		}
		max_len=max(len,max_len);
	}
7-12 分而治之
我感觉这个题对我来说比较难以理解,但只要想到了它在什么情况下不符合,就比较简单了,“待它输入需要查询的城市后,我们用ans[]来记录每一个城市是否有被攻陷的状态,”之后在顺次遍历m条道路,当出现一条道路的两个城市都没有被攻陷的情况,我们就判定它不符合情况。存储两者关系的时候,我们选用结构体来存。
for(int i=0; i<m; i++) {/*说明它两是连通的,连接一条线段的两个端点*/
		cin >> p[i].x >> p[i].y;/*表明它们是连通的*/ 
	}
7-14 社交集群
这一题的解法也是利用并查集来解,
我们对每一种兴趣进行遍历,用book[]数组记录该兴趣是否在先前出现过,若没出现,则用book[]记录其夫节点,,如出现,则利用merg把目前这个人与前一个有该兴趣的人进行合并。
用guess[]对每一个小组的兴趣成员进行计数,num对群体个数进行计数,
核心代码:
for(int i=1;i<=n;i++){
		cin>>n1>>ch;
		for(int j=1;j<=n1;j++){
			cin>>t;
			if(book[t]==0){
				book[t]=i;
			}else{
				merg(book[t],i);/*将两个节点合并*/
			}
		}
	}
	for(int i=1;i<=n;i++){
		if(f[i]==i){
			num++;
		}
		guess[getf(i)]++;
	}