4月2日 周三
《挑战编程:程序设计竞赛训练手册》 第一章 入门
我擦,网真tm烂,只能去刷九度了。
#include <cstdio> #include <memory.h> const int MAXN = 100001; int Tree[MAXN]; int findRoot(int x) { int tmp = x; int ret; while (Tree[x] != 0) { x = Tree[x]; } ret = x; x = tmp; while (Tree[x] != 0) { tmp = Tree[x]; Tree[x] = ret; x = tmp; } return ret; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif int n, m; while (scanf("%d%d", &n, &m) != EOF && n != 0) { memset(Tree, 0, sizeof Tree); while (m--) { int f, t; scanf("%d%d", &f, &t); f = findRoot(f); t = findRoot(t); if (f != t) { Tree[t] = f; } } int ans = 0; for (int i = 1; i <= n; ++i) if (Tree[i] == 0) ans++; printf("%d ", ans); } return 0; }
用位运算的思想来解决:将每一行视为一串二进制数字。
基本的位操作符有与、或、异或、取反、左移、右移这6种,它们的运算规则如下所示:
符号 |
描述 |
运算规则 by MoreWindows |
& |
与 |
两个位都为1时,结果才为1 |
| |
或 |
两个位都为0时,结果才为0 |
^ |
异或 |
两个位相同为0,相异为1 |
~ |
取反 |
0变1,1变0 |
<< |
左移 |
各二进位全部左移若干位,高位丢弃,低位补0 |
>> |
右移 |
各二进位全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移) |