2019.12.7PAT冬季考试第二题 - 7-3 Summit (25分)

35 篇文章 0 订阅

7-3 Summit (25分)

summit (峰会) is a meeting of heads of state or government. Arranging the rest areas for the summit is not a simple job. The ideal arrangement of one area is to invite those heads so that everyone is a direct friend of everyone.

Now given a set of tentative arrangements, your job is to tell the organizers whether or not each area is all set.

Input Specification:

Each input file contains one test case. For each case, the first line gives two positive integers N (≤ 200), the number of heads in the summit, and M, the number of friendship relations. Then M lines follow, each gives a pair of indices of the heads who are friends to each other. The heads are indexed from 1 to N.

Then there is another positive integer K (≤ 100), and K lines of tentative arrangement of rest areas follow, each first gives a positive number L (≤ N), then followed by a sequence of L distinct indices of the heads. All the numbers in a line are separated by a space.

Output Specification:

For each of the K areas, print in a line your advice in the following format:

  • if in this area everyone is a direct friend of everyone, and no friend is missing (that is, no one else is a direct friend of everyone in this area), print Area X is OK..

  • if in this area everyone is a direct friend of everyone, yet there are some other heads who may also be invited without breaking the ideal arrangement, print Area X may invite more people, such as H. where H is the smallest index of the head who may be invited.

  • if in this area the arrangement is not an ideal one, then print Area X needs help. so the host can provide some special service to help the heads get to know each other.

Here X is the index of an area, starting from 1 to K.

Sample Input:

8 10
5 6
7 8
6 4
3 6
4 5
2 3
8 2
2 7
5 3
3 4
6
4 5 4 3 6
3 2 8 7
2 2 3
1 1
2 4 6
3 3 2 1

Sample Output:

Area 1 is OK.
Area 2 is OK.
Area 3 is OK.
Area 4 is OK.
Area 5 may invite more people, such as 3.
Area 6 needs help.

读懂题意很重要。

这道题看上去像是图题,其实更多的是一道模拟题,自己唯一一道AC的题,花了太多的时间,惭愧。

AC的时候距离考试结束已经只有13分钟了,没有时间做第4道题,其实,第4道题更简单分值又高。

1.自己的解法

// ConsoleApplication4.cpp : 定义控制台应用程序的入口点。
//


#include<cstdio>
#include<vector>
#include<iostream>
#include<queue>
#include<stack>
#include<cstring>
#include<string>
#include<set>
#include<algorithm>
using namespace std;


int n, m, l;
const int maxn = 210;
vector<int> wait;
vector<int> Adj[maxn], add;
int add_cnt[maxn] = {0};
int G[maxn][maxn] ={0};
int area_num = 1;
/*
8 10
5 6
7 8
6 4
3 6
4 5
2 3
8 2
2 7
5 3
3 4
6
4 5 4 3 6
3 2 8 7
2 2 3
1 1
2 4 6
3 3 2 1
*/
void makejudge(){
	add.clear();
	fill(add_cnt, add_cnt + maxn, 0);
	sort(wait.begin(), wait.end());
	int head_num = wait.size();
	int cnt; 
	vector<int> friends;
	int flag = 1;
	for(int i = 0; i < head_num; i++){
		if(flag == 0) break;
		for(int j = i + 1; j < head_num; j++){
			if(G[wait[i]][wait[j]] != 1){
				flag = 0;
				break;
			}
		}	
	}
	if(flag == 0){
		printf("Area %d needs help.\n", area_num);
		return;
	}
	set <int> friend_set;
	for(int i = 0; i < head_num; i++){
		friend_set.insert(wait[i]);
	}
	for(int i = 0; i < head_num; i++){
		int head = wait[i];
		for(int j = 0; j < Adj[head].size(); j++){
			int head_friend = Adj[head][j];
			if(friend_set.find(head_friend) == friend_set.end()){
				add_cnt[head_friend]++;
			}
		}
	}
	for(int i = 0; i < maxn; i++){
		if(add_cnt[i] == head_num) add.push_back(i);
	}
	if(add.empty()){
		printf("Area %d is OK.\n", area_num);
	}
	else{
		sort(add.begin(), add.end());
		printf("Area %d may invite more people, such as %d.\n", area_num, add[0]);
	}

}

int main(){
	cin>>n>>m;
	for(int i = 0; i < m; i++){
		int v1, v2;
		scanf("%d%d", &v1, &v2);
		G[v1][v2] = 1;
		G[v2][v1] = 1;
		Adj[v1].push_back(v2);
		Adj[v2].push_back(v1);
	}
	cin>>l;
	for(int i = 0; i< l; i++){
		int num;
		scanf("%d", &num);
		wait.clear();
		for(int j = 0; j < num ; j++){
			int head;
			scanf("%d", &head);
			wait.push_back(head);
		}
		makejudge();
		area_num++;
	}


	return 0;
}

 2大神的解法

isOk判断是否任意两人是friends,if not ok,直接print need help; if ok, 进行下一步判断。

set<>的方法, st.find(),如果找不到,返回st.end()

判断的步骤,找一个不在的head  -> 尝试将head加入summit -> 判断 -> 如果ok,提出建议。 如果遍历完了,还是没有可加入的,打印 area x is ok.

#include <cstdio>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;
const int INF=1000000000;
const int maxN=210;
int G[maxN][maxN]={0};
int isOk(vector<int> summit){
	for (int i=0; i<summit.size(); i++){
		for (int j=i+1; j<summit.size(); j++){
			int u=summit[i];
			int v=summit[j];
			if (G[u][v]!=1){
				return 0;
//				printf("%d %d\n",i,j);
			}
		}
	}
	return 1;
}
int main(){
	int n,m;
	scanf("%d %d",&n,&m);
	for (int i=1; i<=n; i++){
		G[i][i]=1;
	}
	for (int i=0; i<m; i++){
		int u,v;
		scanf("%d %d",&u, &v);
		G[u][v]=G[v][u]=1;
	}
	int k;
	scanf("%d",&k);
	for (int i=0; i<k; i++){
		int l;
		scanf("%d",&l);
		vector<int> summit;
		set<int> st;
		for (int j=0; j<l; j++){
			int index;
			scanf("%d",&index);
			summit.push_back(index);
			st.insert(index);
		}
		if (!isOk(summit)){
			printf("Area %d needs help.\n",i+1);
			continue;
		}
		int k=1;
		for (k=1; k<=n; k++){
			if (st.find(k)==st.end()){
				vector<int> temp=summit;
				temp.push_back(k);
				if (isOk(temp)){
					printf("Area %d may invite more people, such as %d.\n",i+1, k);
					break;
				}
			}
		}
		if (k==n+1) {
			printf("Area %d is OK.\n",i+1);
		}
	}
}

3总结

这道题自己虽然是做出来了,但是实在是做的太烂了,而且思路也很混乱。

通过学习大神的解法,发现解这道题的思路是非常明确的。

1.核心问题:判断head之间是否都是朋友,如果不是,直接出局。因此,要将这一个函数独立出来。

2.在1满足的前提下,判断是否可以加入别的朋友,采用尝试法即可,尝试加入每一个不在set里的朋友,然后再进行判断。

3.如果经过2的检查,确保无遗漏,则可以输出ok。

自己的缺点! 思路不清晰!想要在一个函数中加入太多的功能,导致逻辑混乱,和玩云顶是一样的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值