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