8 59 AAA BBB 10 BBB AAA 20 AAA CCC 40 DDD EEE 5 EEE DDD 70 FFF GGG 30 GGG HHH 20 HHH FFF 10 8 70 AAA BBB 10 BBB AAA 20 AAA CCC 40 DDD EEE 5 EEE DDD 70 FFF GGG 30 GGG HHH 20 HHH FFF 10
2 AAA 3 GGG 3 0
题目大意:
确定一个团队队长的方案是看队员彼此之间的通话时间。如果一个团队中,某个队员和其他队员的通话时间是最长的,那么他就是队长。有一些案例,输入为一些人之间的相互通话时间。找出每个案例中的团队个数,团队个数的限制应该是三人以及三人以上,队员之间所有通话时间大于限制时间K,并且需要找出队长和该队的成员个数。
基本思路:
1、如果要使用数组,需要将字母转换为数字,当然最后输出的时候要转换回去。
2、并查集,读取两个name的时候,就合并。
3、求父节点,并且算出集合个数。
4、对每个集合做计算,求成员个数。符合条件,保留,不符合条件,忽略。
5、按照字母序输出结果。
恩,写的有点泛,再仔细说一下解题思路。
这道题有2个关键点
1、如何确定有几个团队,以及每个团队成员有哪些。
2、在不知道团队成员归属的时候,如何确定团队成员之间的通话时长和每个成员通话时长。
这两个问题一旦想清楚了,题目就迎刃而解了。
1、确定团队以及团队成员,并查集,没什么好说的。只要两者之间相互通话,不管是直接的还是间接的,合并。合并结束之后,求每个成员的父节点,根据并查集思想,如果parent[i] = i,那么i就是该团队的父节点,当然这个节点不一定是队长。
2、确定团队成员之间的通话时长和每个成员通话时长。
使用数组singleCallTime,来记录一个团队成员相互打电话的时间,当然在一开始,我们并不知道,哪些成员是一个团队的,这个也没关系,不会影响记录。在记录时间的时候,比如有个例子是这样的
AAA BBB 10
BBB AAA 20
记录团队电话时间的时候,只记录左侧的通话时间,也就是这两行记录,我们认为是AAA通话10,BBB通话20,不考虑AAA和BBB的相互关系,这样就不会出现重复。同时,在记录每个成员通话时间的时候,需要两边都记录,也就是AAA BBB 10表示AAA打电话10,BBB也打电话10。这样我们就解决了第2个问题。
下一步,我们依次循环团队个数,同时在内层循环,判断每个成员是否属于该团队,如果是,就计算每个成员打电话的时间以及团队成员相互之间电话时间,最后判断是否符合要求。
如果符合要求,排序打印结果,同时注意将数字转换为字符串。
C++ AC
#include <stdio.h> #include <map> #include <vector> #include <string> #include <string.h> #include <algorithm> #include <list> using namespace std; const int maxn = 1002; int parent[maxn]; int n; int k; int i; int currNum; map<string , int> baseMap; char array[maxn][4]; char resultArr[maxn][4]; int callTime[maxn]; int singleCallTime[maxn]; int fatherArr[maxn]; int visit[maxn]; struct Node{ char name[4]; int size; }nodes[maxn]; //并查集寻找父亲节点 int findParent(int f) { while(parent[f] != f){ f = parent[f]; } return f; } //并查集合并节点 void unionTwo(int f, int t) { int a = findParent(f); int b = findParent(t); if (a == b) return; if (a > b) { parent[a] = b; } else { parent[b] = a; } } //初始化基本数据,这在以后会用到 void initData(){ baseMap.clear(); memset(callTime,0,sizeof(callTime)); memset(visit,0,sizeof(visit)); memset(singleCallTime,0,sizeof(singleCallTime)); memset(fatherArr,0,sizeof(fatherArr)); for(i = 1; i < maxn ; i++){ parent[i] = i; } } //将字符串转为数字,否则后面不太好处理 int getCurrentNum(char c[]) { int num = 0; map<string,int>::iterator it = baseMap.find(c); if (it == baseMap.end()) { currNum++; num = currNum; baseMap.insert(make_pair(c,num)); }else { num = it->second; } return num; } //记录每个人打电话的时间 void constructData(char a[], char b[], int anum, int bnum, int d) { if (singleCallTime[anum] == 0) { singleCallTime[anum] = d; }else { singleCallTime[anum] += d; } strcpy(array[anum],a); strcpy(array[bnum],b); callTime[anum] += d; callTime[bnum] += d; } bool cmp(Node node1,Node node2){ return strcmp(node1.name,node2.name)<0; } int main(){ while(scanf("%d%d",&n,&k) != EOF){ initData(); currNum = 0; char a[4]; char b[4]; int d; for(i = 0; i < n; i++){ scanf("%s%s%d",a,b,&d); // printf("%s\n",a); // printf("%s\n",b); int anum = getCurrentNum(a); int bnum = getCurrentNum(b); // printf("%d\n",anum); // printf("%d\n",bnum); constructData(a , b, anum , bnum ,d); unionTwo(anum,bnum); } int tmpk = 1; for (i = 1; i < currNum+1; i++) { parent[i] = findParent(i); // printf("%d\n",parent[i]); if(parent[i] == i){ fatherArr[tmpk] = i; tmpk++; } } //printf("%d\n",tmpk); int num = 0; for (i = 1; i < tmpk; i++) { int size = 0; int allTime = 0; int maxTime = -1; int maxMem = 0; for (int j = 1; j < currNum + 1; j++) { if(fatherArr[i] != 0 && visit[j] == 0){ if(parent[j] == fatherArr[i]){ size++; allTime += singleCallTime[j]; if (callTime[j] > maxTime) { maxTime = callTime[j]; maxMem = j; } visit[j] = 1; } } } if(size < 3){ continue; } if(allTime <= k){ continue; } strcpy(nodes[num].name,array[maxMem]); nodes[num].size = size; num++; } sort(nodes, nodes + num , cmp); printf("%d\n",num); for(i = 0; i < num ; i++){ printf("%s %d",nodes[i].name,nodes[i].size) ; // printf("%d",nodes[i].size) ; printf("\n"); } } return 0; } /************************************************************** Problem: 1446 User: wangzhenqing Language: C++ Result: Accepted Time:30 ms Memory:1096 kb ****************************************************************/
Java AC
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.StreamTokenizer; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; public class Main { /* * 1446 */ private static int parent[]; private static int maxn = 2002; private static int currNum , count; private static Map<String, Integer> baseMap ; private static Map<Integer, List<Integer>> groupMap; private static Map<String, Integer> resultMap; private static String array[] ; private static String keys[] ; private static int callTime[] ,singleCallTime[]; public static void main(String[] args) throws Exception { StreamTokenizer st = new StreamTokenizer(new BufferedReader( new InputStreamReader(System.in))); while (st.nextToken() != StreamTokenizer.TT_EOF) { int n = (int)st.nval; st.nextToken(); int k = (int)st.nval; initParent(n); for (int i = 0; i < n; i++) { st.nextToken(); String a = st.sval; st.nextToken(); String b = st.sval; st.nextToken(); int d = (int)st.nval; int anum = getCurrentNum(a); int bnum = getCurrentNum(b); constructData(a , b, anum , bnum ,d); unionTwo(anum, bnum); } for (int i = 1; i < currNum+1; i++) { parent[i] = findParent(i); } // 具体哪个组包含哪些组员 divideGroup(); // 判断组员个数是不是大于三人,组内通话时间是否大于k; checkNeedResult(k); // 打印结果 printfResult(); } } private static void initParent(int n) { parent = new int[maxn]; for (int i = 1; i < maxn; i++) { parent[i] = i; } baseMap = new HashMap<String, Integer>(); array = new String[maxn]; callTime = new int[maxn]; singleCallTime = new int[maxn]; currNum = 0; } private static void constructData(String a, String b, int anum, int bnum, int d) { if (singleCallTime[anum] == 0) { singleCallTime[anum] = d; }else { singleCallTime[anum] += d; } array[anum] = a; array[bnum] = b; callTime[anum] += d; callTime[bnum] += d; } private static void divideGroup() { groupMap = new HashMap<Integer, List<Integer>>(); for (int i = 1; i < currNum+1; i++) { List<Integer> groupMems = null; if (groupMap.containsKey(parent[i])) { groupMems = groupMap.get(parent[i]); }else { groupMems = new ArrayList<Integer>(); } groupMems.add(i); groupMap.put(parent[i], groupMems); } } private static void checkNeedResult(int k) { keys = new String[currNum+1]; count = 0; resultMap = new HashMap<String, Integer>(); for(Entry<Integer, List<Integer>> entry : groupMap.entrySet()){ List<Integer> groupMems = entry.getValue(); int size = groupMems.size(); if (size < 3) { continue; } int allTime = 0; int maxTime = -1; int maxMem = 0; for (int i = 0; i < size; i++) { int mem = groupMems.get(i); allTime += singleCallTime[mem]; if (callTime[mem] > maxTime) { maxTime = callTime[mem]; maxMem = mem; } } if (allTime <= k ) { continue; } resultMap.put(array[maxMem], size); keys[count] = array[maxMem]; count++; } } private static void printfResult() { Arrays.sort(keys , 0, count); System.out.println(count); for (int i = 0; i < count; i++) { System.out.println(keys[i]+" "+resultMap.get(keys[i])); } } private static int getCurrentNum(String c) { int num = 0; if (!baseMap.containsKey(c)) { currNum++; num = currNum; baseMap.put(c, num); }else { num = baseMap.get(c); } return num; } private static void unionTwo(int f, int t) { int a = findParent( f ); int b = findParent( t ); if (a == b) return; if (a > b) { parent[a] = b; } else { parent[b] = a; } } private static int findParent(int f) { while (parent[f] != f) { f = parent[f]; } return f; } } /************************************************************** Problem: 1446 User: wangzhenqing Language: Java Result: Accepted Time:290 ms Memory:28428 kb ****************************************************************/