湖南省赛2010

Problem A -> I

source

uva11877 -> 11885

solution

这些题都很挺简单的, 我们队1个半小时就把前6个题过了.

做法上, D模拟就可以了, 但我觉得有点小蛋疼, 我的想法是竖直或水平的情况特判, 其余情况按方向向量在四个方向讨论, 训练的时候这个题并不是我写的.

F题直接dfs, 加上一个剪支, 因为路径会把原图分成多个连通块, 所以每次找出当前连通块内所有数, 假设它们可以任意排列, 然后和已经搜到的串拼起来, 如果不比当前答案优, 那么就没必要继续搜下去.

I题不会推, 但是打个表很容易就找到规律了, 貌似我们队在这方面比较迟钝, 好几次打表都没太反应过来.


Problem J - Infinite Dictionaries

source

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=226&page=show_problem&problem=3008

solution

这真是个蛋疼题, 训练的时候我傻逼了, 以为reference是可以传递的, 实际上题目中的赋值指的就是指针赋值, 就和java的赋值一样.

这个题的难度就在实现上, 我的想法大概是这样的.

首先INTEGER和STRING可以看成同一种类型, 我都当作了std::string, 这里有个trick是整数可能为负, 我没有判断负号, RE了很多次.

做了这样的转换以后, 数据类型就只有std::string和dict两种了.

由于dict里面有很多pair, pair的第一个类型一定是std::string, 但是第二个就不一定了.

为了处理这种情况, 我把std::string和dict打包成了一个struct Complex, 里面有int data_type, std::string string, std::map <std::string, Complex*> dict;

data_type表示这个Complex是那种数据, string和dict就分别用于记录, 这样虽然会有一点内存的浪费, 但是实现dict就很容易了, 直接上std::map.

然后对于length操作, 直接返回std::map的size就可以了, 对于test, 实际上各个dict之间构成了一个有向图, 判断这个有向图有没有环就可以了(包括自环), 把tarjan求强连同分量的算法稍微修改一下即可.

对于assign操作, 我写了两个函数, parse_reference, 这个函数返回对Complex*的引用, 等号左边的部分调用这个函数就可以了, 等号右边的部分调用parse, 这个函数集成了需要new一个dict, new一个string和parse_reference三种情况, 返回的是Complex*.

对于parse_reference, 为了方便, 因为直接的变量只有26个, 所以我开了个全局变量Complex* ptr[26];

想清楚以后剩下的工作就很简单了.

一个可能的trick是[]操作可以取到一个原来没有的pair, 需要自己new出来.

#include <cstdio>
#include <algorithm>
#include <string>
#include <cassert>
#include <cctype>
#include <cstring>
#include <vector>
#include <set>
#include <map>

struct Complex;
typedef Complex* ComplexPointer;

int total_nodes;

struct Complex {
	static const int STRING = 0;
	static const int DICT = 1;

	int data_type, id;
	std::string string;
	std::map <std::string, ComplexPointer> dict;

	Complex() {
		data_type = DICT;
		id = total_nodes++;
	}

	Complex(const std::string& s) {
		data_type = STRING;
		string = s;
		id = total_nodes++;
	}

	int length() const {
		return (int)dict.size();
	}

	ComplexPointer& operator[](const std::string& s) {
		if (!dict.count(s)) {
			dict[s] = new Complex;
		}
		return dict[s];
	}

	void add_pair(const std::string& first, const ComplexPointer& second) {
		dict[first] = second;
	}
};

inline int id(char x) {
	return x - 'a';
}

const int MAX_LENGTH = 333;
char buf[MAX_LENGTH];
ComplexPointer ptr[26];

ComplexPointer new_dict(int s, int t) {
	#define CLR() (state = 0, first = second = "")
	static std::vector <std::string> que_str;
	static std::vector <ComplexPointer> que_ptr;
	std::string first, second;
	int state = 0;
	que_str.clear();
	que_ptr.clear();
	for (; s < t; s++) {
		if (buf[s] == '{') {
			que_str.push_back(first);
			que_ptr.push_back(new Complex);
			CLR();
		} else if (buf[s] == '}') {
			if (state == 1) {
				que_ptr.back()->add_pair(first, new Complex(second));
				CLR();
			}
			ComplexPointer ptr = que_ptr.back();
			que_ptr.pop_back();
			if (que_ptr.empty()) {
				return ptr;
			}
			que_ptr.back()->add_pair(que_str.back(), ptr);
			que_str.pop_back();
		} else if (buf[s] == ',') {
			if (state == 1) {
				que_ptr.back()->add_pair(first, new Complex(second));
				CLR();
			}
		} else if (buf[s] == ':') {
			state = 1;
		} else {
			state == 0 ? first += buf[s] : second += buf[s];
		}
	}
	return que_ptr.front();
}

ComplexPointer& parse_reference(int s, int t) {
	if (s + 1 == t) {
		return ptr[id(buf[s])];
	}
	ComplexPointer now = ptr[id(buf[s++])];
	while (s < t) {
		int l = s + 1, r = s + 1;
		for (; buf[r] != ']'; r++);
		if (r + 1 == t) {
			return (*now)[std::string(buf + l, buf + r)];
		} else {
			now = (*now)[std::string(buf + l, buf + r)];
			s = r + 1;
		}
	}
}

ComplexPointer parse(int s, int t) {
	if (buf[s] == '{') {
		return new_dict(s, t);
	} else if (buf[s] == '\'' || isdigit(buf[s]) || buf[s] == '-') {
		return new Complex(std::string(buf + s, buf + t));
	} else {
		return parse_reference(s, t);
	}
}

std::set <int> visited, stack;

bool dfs(ComplexPointer ptr) {
	visited.insert(ptr->id);
	stack.insert(ptr->id);
	for (__typeof(ptr->dict.begin()) itr = ptr->dict.begin(); itr != ptr->dict.end(); itr++) {
		if (!visited.count(itr->second->id) && dfs(itr->second)) {
			return true;
		} else if (stack.count(itr->second->id)) {
			return true;
		}
	}
	stack.erase(ptr->id);
	return false;
}

int test(ComplexPointer ptr) {
	visited.clear();
	stack.clear();
	return dfs(ptr);
}

int main() {
	for (int i = 0; i < 26; i++) {
		ptr[i] = new Complex;
	}

	while (gets(buf)) {
		int l = strlen(buf), m = 0;
		for (int i = 0; i < l; i++) {
			if (buf[i] != ' ') {
				buf[m++] = buf[i];
			}
		}
		l = m;
		if (l >= 4 && std::string(buf, buf + 4) == "test" ) {
			printf("%d\n", test(parse(5, l - 1)));
		} else if (l >= 6 && std::string(buf, buf + 6) == "length") {
			printf("%d\n", parse(7, l - 1)->length());
		} else {
			for (int i = 0; i < l; i++) {
				if (buf[i] == '=') {
					parse_reference(0, i) = parse(i + 1, l);
					break;
				}
			}
		}
	}
}

Problem K - Tetrahedrons and Spheres

source

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=226&page=show_problem&problem=3009

solution

开场的时候随便看了一下题, 瞥到了"Special Thanks: Jingbo Shang", 后来队友告诉我是个三维几何, 我就知道这个题要蛋疼了.

比赛的后三个小时我一直在做J, 因为refenrence理解错的原因一直蛋疼的RE, 队友一直在用simpson套simpson的方法做, 但是精度一直不够, 样例都过不了.

到现在我也没过这个题, std的做法倒是很简单, 一维simpson积分, 另一维梯形剖分. 我只能表示不会几何, 从来没写过梯形剖分, 这个题也只能暂时这样了, 后面学了梯形剖分再来过掉.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值