NYOJ130 同样的雪花 【Hash】

同样的雪花

时间限制:1000 ms  |  内存限制:65535 KB

难度:4

描写叙述
You may have heard that no two snowflakes are alike. Your task is to write a program to determine whether this is really true. Your
program will read information about a collection of snowflakes, and search for a pair that may be identical. Each snowflake has six arms. For each snowflake, your program will be provided with a measurement of the length of each of the six arms. Any pair of
snowflakes which have the same lengths of corresponding arms should be flagged by your program as possibly identical.

输入
The first line of the input will contain a single interger T(0<T<10),the number of the test cases.

The first line of every test case will contain a single integer n, 0 < n ≤ 100000, the number of snowflakes to follow. This will be followed by n lines, each describing a snowflake. Each snowflake will be described by a line containing six integers (each integer
is at least 0 and less than 10000000), the lengths of the arms of the snow ake. The lengths of the arms will be given in order around the snowflake (either clockwise or counterclockwise), but they may begin with any of the six arms. For example, the same snowflake
could be described as 1 2 3 4 5 6 or 4 3 2 1 6 5.

输出
For each test case,if all of the snowflakes are distinct, your program should print the message:

No two snowflakes are alike.

If there is a pair of possibly identical snow akes, your program should print the message:

Twin snowflakes found.

例子输入
1
2
1 2 3 4 5 6
4 3 2 1 6 5
例子输出
Twin snowflakes found.
来源
POJ
上传者
张云聪

题意:给定多组包括6组数的序列,推断当中是否有两组是相等的,相等的根据是这两组数正序匹配或者逆序匹配。

题解:以每组的和为key对每片雪花进行哈希,然后从和相等的雪花里进行匹配。

#include <stdio.h>
#include <string.h>
#include <vector>

#define maxn 100001
#define MOD 100001

int n;
struct Node {
	int a[6];
} snow[maxn];
std::vector<int> f[MOD];

void getData() {
	int i, j, sum;
	memset(f, 0, sizeof(f));
	scanf("%d", &n);
	for(i = 0; i < n; ++i) {
		for(j = sum = 0; j < 6; ++j) {
			scanf("%d", &snow[i].a[j]);
			sum += snow[i].a[j];
		}
		f[sum % MOD].push_back(i);
	}
}

bool Judge(int x, int y) {
	int i, j, count;
	for(i = 0; i < 6; ++i) {
		if(snow[x].a[i] == snow[y].a[0]) {
			for(count = j = 0; j < 6; ++j)
				if(snow[x].a[(i+j)%6] == snow[y].a[j])
					++count;
			if(count == 6) return true;

			for(count = j = 0; j < 6; ++j)
				if(snow[x].a[((i-j)%6+6)%6] == snow[y].a[j])
					++count;
			if(count == 6) return true;
		}
	}
	return false;
}

bool test(int k, int m) {
	int i, j;
	for(i = 0; i < m; ++i)
		for(j = i + 1; j < m; ++j)
			if(Judge(f[k][i], f[k][j]))
				return true;
	return false;
}

void solve() {
	int i, j, k, ok = 0;
	for(i = 0; i < MOD; ++i)
		if(!f[i].empty() && test(i, f[i].size())) {
			ok = 1; break;
		}
	printf(ok ? "Twin snowflakes found.\n"
		: "No two snowflakes are alike.\n");
}

int main() {
	// freopen("stdin.txt", "r", stdin);
	int t;
	scanf("%d", &t);
	while(t--) {
		getData();
		solve();
	}
	return 0;
}

然后又尝试了下链表:结果TLE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define maxn 100001

int n;
struct Node {
	int a[6];
	Node *next;
};
struct Node2 {
	int sum;
	Node2 *nextNode2;
	Node *next;
} root;

void insertNode(Node2 *n2p, Node tmp) {
	Node *p = (Node *) malloc(sizeof(Node));
	*p = tmp; p->next = n2p->next;
	n2p->next = p;
}

void insertNode2(int sum, Node tmp) {
	Node2 *p = root.nextNode2, *q = &root;
	while(true) {
		if(!p || p->sum > sum) {
			Node2 *temp = (Node2 *) malloc(sizeof(Node2));
			temp->sum = sum; temp->nextNode2 = p;
			temp->next = NULL; q->nextNode2 = temp;
			insertNode(temp, tmp);
			return;
		} else if(p->sum == sum) {
			insertNode(p, tmp);
			return;
		}
		q = p; p = p->nextNode2;
	}
}

void destoryNode(Node *p) {
	Node *q;
	while(p) {
		q = p; p = p->next;
		free(q);
	}
}

void destoryNode2(Node2 *p) {
	Node2 *q;
	while(p) {
		destoryNode(p->next);
		q = p; p = p->nextNode2;
		free(q);
	}
}

void getData() {
	int i, j, sum; Node tmp;
	destoryNode2(root.nextNode2);
	root.nextNode2 = NULL;
	root.next = NULL;
	root.sum = -1;
	scanf("%d", &n);
	for(i = 0; i < n; ++i) {
		for(j = sum = 0; j < 6; ++j) {
			scanf("%d", &tmp.a[j]);
			sum += tmp.a[j];
		}
		insertNode2(sum, tmp);
	}
}

bool JudgeArr(int a[], int b[]) {
	int i, j, cnt;
	for(i = 0; i < 6; ++i) {
		if(a[i] == b[0]) {
			for(j = cnt = 0; j < 6; ++j)
				if(a[(i+j)%6] == b[j]) ++cnt;
			if(cnt == 6) return true;

			for(j = cnt = 0; j < 6; ++j)
				if(a[(i-j+6)%6] == b[j]) ++cnt;
			if(cnt == 6) return true;
		}
	}
	return false;
}

bool JudgeList(Node *pn) {
	Node *p1, *p2;
	for(p1 = pn; p1; p1 = p1->next) {
		for(p2 = p1->next; p2; p2 = p2->next)
			if(JudgeArr(p1->a, p2->a)) return true;
	}
	return false;
}

void solve() {

	Node *np;
	for(Node2 *n2p = root.nextNode2; n2p; n2p = n2p->nextNode2) {
		if(JudgeList(n2p->next)) {
			printf("Twin snowflakes found.\n");
			return;
		}
	}
	printf("No two snowflakes are alike.\n");
}

int main() {
	// freopen("stdin.txt", "r", stdin);
	int t;
	scanf("%d", &t);
	while(t--) {
		getData();
		solve();
	}
	return 0;
}
时间: 2024-08-29 08:39:02

NYOJ130 同样的雪花 【Hash】的相关文章

NYOJ130 相同的雪花 【Hash】

相同的雪花 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 You may have heard that no two snowflakes are alike. Your task is to write a program to determine whether this is really true. Your program will read information about a collection of snowflakes, and searc

相同的雪花 Hash

相同的雪花 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 You may have heard that no two snowflakes are alike. Your task is to write a program to determine whether this is really true. Your program will read information about a collection of snowflakes, and searc

nyoj130 相同的雪花_未验证

代码: #include <iostream> #include <cstdio> using namespace std; typedef struct snow{ int a[6]; snow *next; }; snow *s[100000]; int fin(int b[],int sum){ snow *p; p=s[sum]->next; while(p){ for(int i=0;i<6;i++){ int j; if(b[i]==p->a[0]){

POJ 3349 HASH

题目链接:http://poj.org/problem?id=3349 题意:你可能听说话世界上没有两片相同的雪花,我们定义一个雪花有6个瓣,如果存在有2个雪花相同[雪花是环形的,所以相同可以是旋转过后相同]则输出“Twin snowflakes found.”,否则输出“No two snowflakes are alike.”. 思路:最简单的就是两两判断,但是这样的复杂度为O(n^2),TLE.所以我们要尽量减少判断次数,我们用把拥有6个瓣的雪花HASH成一个数字,只有两个雪花用有相同HA

POJ 3349 Snowflake Snow Snowflakes(哈希表)(转)

题意:判断有没有两朵相同的雪花.每朵雪花有六瓣,比较花瓣长度的方法看是否是一样的,如果对应的arms有相同的长度说明是一样的.给出n朵,只要有两朵是一样的就输出有Twin snowflakes found.,如果任何两个都是不一样的输出No two snowflakes are alike.n=100,000. 思路:最 简单的就是枚举每两片雪花,判断他们是否相同.时间复杂度为O(n*n),显然效果不理想.有没有更好的算法呢?hash:每读进一片雪花,将雪花 hash,判断hash表里是否有相同

【hash表】收集雪花

[哈希和哈希表]收集雪花 题目描述 不同的雪花往往有不同的形状.在北方的同学想将雪花收集起来,作为礼物送给在南方的同学们.一共有n个时刻,给出每个时刻下落雪花的形状,用不同的整数表示不同的形状.在收集的过程中,同学们不希望有重复的雪花.你可以从任意a时刻开始,在b时刻停止.a到b时刻中间的雪花也都将被收集.他们希望收集的雪花最多. 输入 第一行一个正整数n:第2行到第n+1行表示n个时刻雪花的形状. 输出 最多能收集雪花的数量. 样例输入 5 1 2 3 2 1 样例输出 3 提示 n≤1e6,

[poj3349]Snowflake Snow Snowflakes(hash)

Snowflake Snow Snowflakes Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 37615 Accepted: 9882 Description You may have heard that no two snowflakes are alike. Your task is to write a program to determine whether this is really true. Your

hash应用以及vector的使用简介:POJ 3349 Snowflake Snow Snowflakes

今天学的hash.说实话还没怎么搞懂,明天有时间把知识点总结写了,今天就小小的写个结题报告吧! 题意: 在n (n<100000)个雪花中判断是否存在两片完全相同的雪花,每片雪花有6个角,每个角的长度限制为1000000 两片雪花相等的条件: 雪花6个角的长度按顺序相等(这个顺序即可以是顺时针的也可以是逆时针的) 解题思路: hash:连加求余法 求key 值,链地址法解决冲突,连加求余法 求key 值挺简单,关于链地址法解决冲突可以通过c++中,vector容器可以较为方便的实现. 下面先介绍

poj 3349 数组的hash(最常用、最普通的哈希表建立)

http://poj.org/problem?id=3349 Description You may have heard that no two snowflakes are alike. Your task is to write a program to determine whether this is really true. Your program will read information about a collection of snowflakes, and search