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)]++;
} 


京公网安备 11010502036488号