You Who?
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 801 | Accepted: 273 |
Description
On the first day of first grade at Friendly Elementrary School, it is customary for each student to spend one minute talking to every classmate that he or she does not already know. When student Bob sees an unfamilar face, he says “You who?” A typical response is “Me Charlie, you who?” Then Bob says, “Me Bob!” and they talk for a minute. It’s very cute. Then, after a minute, they part and each looks for another stranger to greet. This takes time. In class of twenty-nine or thirty mutual strangers, it takes 29 minutes; time that, according to teachers, could be better spent learning the alphabet. Of course, it is rare to have a first grade class where nobody knows anyone else; there are neighbors and playmates who already know each other, so they don’t have to go through the get-to-know-you minutes with each other.
The two first grade teachers have requested that, to save time, students be allocated to their two classes so that the difference in the sizes of the classes is at most one, and the time it takes to complete these introductions is as small as possible. There are no more than 60 students in the incoming first grade class.
How can the assignment of students to classes be made? Your job is to write the software that answers the question.
Input
The school records include information about these student friendships, represented as lists of numbers. If there are 29 students, then they are represented by the numbers 1 to 29. The record for a single student includes, first, his/her student identification number (1 to 29, in this example), then the number of his/her acquaintances, then a list of them in no particular order. So, for example, this record
17 4 5 2 14 22
indicates that student 17 knows 4 students: 5, 2, and so on. The records for all the students in the incoming class are represented as the list of numbers that results from concatenating all the student records together. Spaces and line breaks are irrelevent in this format. Thus, this
1 1 2 2 1 1
is a whole database, indicating that there are only two students in the incoming class, and they know each other; and this
1 2 3 4
2 2 3 4
3 2 1 2
4 2 1 2
indicates that 1 doesn’t know 2, and 3 doesn’t know 4, but all other pairs know each other.
The database has been checked for consistency, so that if A knows B, then B knows A.
Output
Your output should begin with a number that tells how long it will take to complete the introductions in the best possible legal class assignment. For the simple two student problem above, the only legal answer is
0
Sample Input
1 2 3 4 2 2 3 4 3 2 1 2 4 2 1 2
Sample Output
0
Hint
To make this problem more tractable, the following changes are being made. There will be exactly two classes. There will be no more that 30 students. The students will be divided as evenly as possible between the classes. The loneliness of a student is the number of students in his class whom he does not know. You are to arrange the classes to minimize the loneliness of the loneliest student. for the sample data ,you can arrange 1 and 3 to the first class,and 2 and 4 to the second class,then they need no time to know each other.
cangratul提醒:
我本来的程序中有考虑最大不认识的人数是否需要加1的情况,结果被判wrong。 最近找了个当年比赛的标准程序,发现其本意还真是只要找所有分组情况中,两组里最大不认识的人数最小的那个情况即可。 并且原题的测试数据也是这个: Judge's Input 1 0 2 0 3 0 4 0 5 0 Judge's Output 2 2 1 2 3 3 4 5 可能编题目的作者也没有料到有这个(浅显的)问题,于是整个背景叙述就显得如此荒诞了。 POJ简化题目——班级的输出免了,但误人的背景留了下来。 顺便说一下,标程是用非常复杂的位运算实现的,这样和人多人少关系就不大了。 总人数最多是30个(于是每个人与他人的关系、每个班的组成(最多15个人)都可以用一个unsigned表示),算法就是穷举。
分析:题目对我来说感觉蛮难理解的,可能是因为数学太弱?这个题目数据比较弱,poj上最多4个students,所以算是水题了。
/* 1 2 3 4 2 2 3 4 3 2 1 2 4 2 1 2 */ #include "stdio.h" #include "stdlib.h" #include "string.h" #define MAX_STUDENT 30 int gwFriendList[MAX_STUDENT+1][MAX_STUDENT+1]; int gwdivide[MAX_STUDENT+1]; int gwStudentNum; int MAX(int a, int b) { return (a>b) ? a : b; } int MIN(int a, int b) { return (a>b) ? b : a; } int strangeNum(int wboy, int class[]) { int i = 0; int j = 0; int lone = 0; for(i=1; i<=class[0]; i++) { if(wboy == class[i]) continue; for(j=1; j<=gwFriendList[class[i]][0]; j++) { if(wboy == gwFriendList[class[i]][j]) break; } if(j > gwFriendList[class[i]][0]) lone++; } return lone; } void exchangeValue(int *a, int *b) { int tmp; tmp = *a; *a = *b; *b = tmp; } void buildClass(int class[], int flag) { int i = 0; int j = 0; for(i=1; i<=gwStudentNum; i++) { if(gwdivide[i] == flag) class[++j] = i; } class[0] = j; } int calcLone(int class[]) { int i = 0; int lone = 0; for(i=1; i<=class[0]; i++) { lone = MAX(lone, strangeNum(class[i], class)); } return lone; } int Lone() { int class1[MAX_STUDENT+1]; int class2[MAX_STUDENT+1]; buildClass(class1, 1); buildClass(class2, 0); return MAX(calcLone(class1), calcLone(class2)); } int divideClass(int now, int max) { int wlone = 30; int i = 0; if(now == max) return Lone(); else { wlone = MIN(wlone, divideClass(now+1, max)); for(i=now+1; i<=max; i++) { if(gwdivide[i] != gwdivide[max]) { exchangeValue(&gwdivide[i], &gwdivide[max]); wlone = MIN(wlone, divideClass(i, max)); exchangeValue(&gwdivide[i], &gwdivide[max]); } } return wlone; } } int main() { int i = 0; int j = 0; int wCount = 0; int lone = 0; while(1) { if(EOF == scanf("%d", &j)) break; scanf("%d", &wCount); gwFriendList[j][0] = wCount; gwStudentNum++; for(i=1; i<=wCount; i++) { scanf("%d", &gwFriendList[j][i]); } wCount = 0; } for(i=1; i<=(gwStudentNum/2); i++) { gwdivide[i] = 1; } lone = divideClass(1,gwStudentNum); printf("%d\n", lone); return 0; }