思路:一开始考虑n个朋友可以有c种可能,根据回答的问题,如果是yes那么可以确定一些朋友的范围,将原本不在这个范围内的删除即可;如果是“no”,说明这些朋友都应该被删除,那么最后看第i个人候选的情况是不是只有一种,如果是直接输出名字,否则就是不确定或者不存在。下面介绍利用贡献优化,并且非常好写的方法。

AC代码

#include <cstdio>
#include <cmath>
#include <cctype>
#include <algorithm>
#include <cstring>
#include <utility>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define eps 1e-10
#define inf 0x3f3f3f3f
#define PI pair<int, int>
typedef long long LL;
const int maxn = 200 + 5;
string name[maxn];
int vis[maxn][maxn];
int a[maxn][maxn];
map<string, int>ha;
int getId(string p) {
	return ha[p];
}
int main() {
	int T, n, q, c;
	scanf("%d", &T);
	while(T--) {
		ha.clear();
		scanf("%d%d", &n, &q);
		scanf("%d", &c);
		for(int i = 0; i < c; ++i) {
			cin >> name[i];
			ha[name[i]] = i;
		}
		vector<int>que[maxn];
		memset(vis, 0, sizeof(vis));
		for(int i = 0; i < q; ++i) {
			int m;
			scanf("%d", &m);
			string s;
			for(int j = 0; j < m; ++j) {
				cin >> s;
				que[i].push_back(getId(s));
			}
		}
		for(int i = 0; i < n; ++i) {
			for(int j = 0; j < c; ++j) vis[i][j] = 1;
			for(int j = 0; j < q; ++j) {
				scanf("%d", &a[i][j]);
				if(a[i][j]) {
					for(int k = 0; k < c; ++k) if(vis[i][k]) {
						int f = 0;
						for(int h = 0; h < que[j].size(); ++h) {
							if(que[j][h] == k) {
								f = 1;
								break;
							}
						}
						if(!f) vis[i][k] = 0;
					}
				}
				else {
					for(int k = 0; k < que[j].size(); ++k) {
						vis[i][que[j][k]] = 0;
					}
				}
			}
		}
		for(int i = 0; i < n; ++i) {
			int cnt = 0;
			int ind;
			for(int j = 0; j < c; ++j) {
				if(vis[i][j]) {
					++cnt;
					ind = j;
				}
			}
			if(cnt == 1) {
				cout << name[ind] << endl;
			}
			else printf("Let's go to the library!!\n");
		}
	}
	return 0;
}

更好的思路:每一个人被每一个问题赋予了一定的贡献,第i个问题的贡献是2^i(二进制)。

例如:

4 Serval Raccoon Alpaca Moose

1 Serval

1 Fennec

1 Serval

第一个问题对Serval Raccoon Alpaca Moose四人的贡献为2^0,

第二个问题对Serval贡献为2^1,下面的问题同理;“”

最后根据对问题的回答情况,确定第i(0 < i < n)人的贡献,查找人名中是否有唯一与之对应的,如果有输出人名,否则输出“Let's go to the library!!”,时间复杂度为O(n*c)。这种方法非常巧妙,降低了复杂度。

AC代码

#include <cstdio>
#include <cmath>
#include <cctype>
#include <algorithm>
#include <cstring>
#include <utility>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define eps 1e-10
#define inf 0x3f3f3f3f
#define PI pair<int, int>
typedef long long LL;
const int maxn = 200 + 5;
string name[maxn];
map<string, int>ha;
int w[30], g[maxn];
void init() {
	w[0] = 1;
	for(int i = 1; i <= 25; ++i) w[i] = w[i-1] * 2;
}
int main() {
	init();
	int T, n, q, c;
	scanf("%d", &T);
	while(T--) {
		ha.clear();
		scanf("%d%d", &n, &q);
		scanf("%d", &c);
		for(int i = 0; i < c; ++i) {
			cin >> name[i];
			ha[name[i]] = i;
			g[i] = 0;
		}
		for(int i = 0; i < q; ++i) {
			string s;
			int m;
			scanf("%d", &m);
			while(m--) {
				cin >> s;
				g[ha[s]] += w[i];
			}
		}
		for(int i = 0; i < n; ++i) {
			int sum = 0;
			for(int j = 0; j < q; ++j) {
				int f;
				scanf("%d", &f);
				if(f) sum += w[j];
			}
			int cnt = 0, peo;
			for(int j = 0; j < c; ++j) {
				if(g[j] == sum) {
					++cnt;
					peo = j;
				}
			}
			if(cnt == 1) cout << name[peo] << endl;
			else printf("Let's go to the library!!\n");
		}
	}
	return 0;
}

由于测试数据不够强,导致二种方法时间相差不大:强烈建议掌握第二种的思路。

如有不当之处欢迎指出!

浙江省赛 C What Kind of Friends Are You?的更多相关文章

  1. ZOJ 3879 Capture the Flag 15年浙江省赛K题

    每年省赛必有的一道模拟题,描述都是非常的长,题目都是蛮好写的... sigh... 比赛的时候没有写出这道题目 :( 题意:首先输入4个数,n,q,p,c代表有n个队伍,q个服务器,每支队伍的初始分数 ...

  2. The 13th Zhejiang Provincial Collegiate Contest(2016年浙江省赛)

      前4道水题就不说了,其中我做了C题,1Y,小心仔细写代码并且提交之前得确认无误后提交才能减少出错率. 结果后面2题都由波神做掉,学长带我们飞~ 终榜 官方题解   ZOJ 3946 Highway ...

  3. ZOJ 3872 Beauty of Array DP 15年浙江省赛D题

    也是一道比赛时候没有写出来的题目,队友想到了解法不过最后匆匆忙忙没有 A 掉 What a pity... 题意:定义Beauty数是一个序列里所有不相同的数的和,求一个序列所有字序列的Beauty和 ...

  4. (2017浙江省赛E)Seven Segment Display

    Seven Segment Display Time Limit: 2 Seconds      Memory Limit: 65536 KB A seven segment display, or ...

  5. 浙江省赛之Singing Everywhere

    题目:http://acm.zju.edu.cn/onlinejudge/showContestProblem.do?problemId=5996 方法: 在大佬的指导下完成. 寻找峰值,找到一共k个 ...

  6. 2019浙江省赛B zoj4101 Element Swapping(推公式)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=6003 题意 \(数组a通过交换一对数字,得到了b数组,给出x=\sum^n_{ ...

  7. 2019浙江省赛K zoj4110 Strings in the Pocket(manachar)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=6012 题意 给你两个串,可以翻转a串的一个区间,问有多少对l,r使得翻转后的a ...

  8. 140 - The 12th Zhejiang Provincial Collegiate Programming Contest(浙江省赛2015)

      Ace of Aces Time Limit: 2 Seconds      Memory Limit: 65536 KB There is a mysterious organization c ...

  9. 浙江省赛 ZOJ4029

    Now Loading!!! Time Limit: Second Memory Limit: KB DreamGrid has integers . DreamGrid also has queri ...

随机推荐

  1. Azure VM 防止被入侵

    伴随着开源Linux系统的逐渐盛行,在机器上线之前配置好安全策略至关重要,分享几点有关Azure Linux VM机器的安全建议如下: 1.禁止root账号登录虚拟机,并增加密码的复杂度(大小写字母, ...

  2. java基础-静态,非静态(构造)代码块,类加载

    static block and non-static block(constructor block) [toc] 想来想去,先来一题比较好 public class Foo { public st ...

  3. asp.net web api 向客户端返回错误信息

    1使用Http状态码 ASP.NET Web Api框架提供了Http状态码的值,如下图所示. 虽然有这些预定义的状态码,但在实际项目中使用自定状态码结合预定义状态码更有优势. 通过在适当的位置抛出异 ...

  4. redis数据类型-列表类型

    列表类型 列表类型(list)可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的某一个片段. 列表类型内部是使用双向链表(double linked list)实现的,所以向 ...

  5. fopen fclose feof fgets fetl

    fopen :Open file, or obtain information about open files 例如 fid = fopen(filename, permission)%许可包括: ...

  6. Struts2实现文件上传和下载,多文件上传,限制文件大小,限制文件类型

    文件上传使用的包:commons-upload-xx.jar                                 commons-io-xx.jar 一.实现文件上传: 1.在表单空间中添 ...

  7. 网页转图片--- html2canvas截图

    最近有个做在线名片(可保存图片至本地)的任务,特意研究了一下图片生成,也踩了几个坑.特此总结一下,顺便分享一下demo: 链接:https://pan.baidu.com/s/1o98UBJO 密码: ...

  8. KBEngine游戏服务器(一)——引擎环境配置

    系统:Win10 版本:Visual Studio 2013(也就是vs120) kbengine:v1.0.0 MySQL:5.7 MySQL Workbench :6.3 一.下载kbengine ...

  9. Trusted Execution Technology (TXT) --- 启动控制策略(LCP)篇

    版权声明:本文为博主原创文章,未经博主允许不得转载.http://www.cnblogs.com/tsec/p/8428631.html 在TXT平台中,启动控制策略(Launch Control P ...

  10. 轮询、长轮询、长连接、flash socket 的区别

    轮询:客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并关闭连接. 优点:后端程序编写比较容易. 缺点:请求中有大半是无用,浪费带宽和服务器资源. 实例:适于小型应用. 长轮询:客 ...