秤 \operatorname{秤} 秤
题目链接: jzoj 1500 \operatorname{jzoj\ 1500} jzoj 1500
题目
秤是由秤杆、绳、和物品组成,每个秤杆被一根连着中点处的绳子挂着,杆子的两端也都挂着一根绳子,下面可以直接挂物品,也可以挂另一个秤杆,秤杆可以任意旋转。
现在给你两把秤,要求判断这两把秤是否一样。秤的表示方法如下,假设秤一共有 N N N 个秤杆,用 1 1 1 到 N N N 来编号, 1 1 1 号秤杆总是最上面的那个秤杆,每个秤杆两边悬挂物品或者是另一个秤杆,物品用一个负数或 0 0 0 来表示物品的种类 ( − 9999..0 ) (-9999..0) (−9999..0) ,而用正数表示悬挂的秤杆的编号。
输入
输入包含两把秤的描述,秤的描述方法如下:第一行输入一个整数 N ( 1 < = N < = 100 , 000 ) N(1<=N<=100,000) N(1<=N<=100,000) 表示秤中秤杆的数量,接下来 N N N 行,每行两个整数,表示第 i i i 个秤杆两边悬挂的情况。
输出
如果两把秤不同输出 “Fred and Mary have different mobiles.” ,否则输出 “Fred and Mary might have the same mobile.” 。
样例输入1
5
2 3
4 5
-1 -2
-3 -4
-5 -6
5
2 5
-1 -2
-3 -4
-5 -6
3 4
样例输出1
Fred and Mary might have the same mobile.
样例输入2
5
2 3
4 5
-3 -4
-1 -2
-5 -6
5
2 5
-1 -2
-3 -4
-5 -6
3 4
样例输出2
Fred and Mary have different mobiles.
思路
这道题就是一道搜索。
我们可以看出,题目就是要我们看两个二叉树是否相等。
那我们就直接分类讨论搜索,就可以了。
代码
#include<cstdio>
#include<algorithm>
using namespace std;
int n, m, a[3][100001], b[3][100001], ch[100001];
bool yes;
bool dfs(int x, int y) {
if (a[1][x] <= 0 && a[2][x] <= 0) {
if (a[1][x] == b[1][y] && a[2][x] == b[2][y]) return 1;//挂的都是物体且相同
return 0;
}
else if (a[1][x] <= 0 && a[2][x] > 0) {
if (a[1][x] == b[1][y] && dfs(a[2][x], b[2][y])) return 1;//一边物体,一边秤
return 0;
}
else {
if (dfs(a[1][x], b[1][y]) && dfs(a[2][x], b[2][y])) return 1;//两边都是秤
if (dfs(a[2][x], b[1][y]) && dfs(a[1][x], b[2][y])) return 1;
return 0;
}
}
int main() {
scanf("%d", &n);//读入
for (int i = 1; i <= n; i++) {
scanf("%d %d", &a[1][i], &a[2][i]);//读入
if (a[1][i] > a[2][i]) swap(a[1][i], a[2][i]);//让小的一定放在前面,方便后面比较
}
scanf("%d", &m);//跟上面一样
for (int i = 1; i <= m; i++) {
scanf("%d %d", &b[1][i], &b[2][i]);
if (b[1][i] > b[2][i]) swap(b[1][i], b[2][i]);
}
if (n != m) {
//数量都不同肯定不一样
printf("Fred and Mary have different mobiles.");
return 0;
}
if (dfs(1, 1)) printf("Fred and Mary might have the same mobile.");//输出
else printf("Fred and Mary have different mobiles.");
return 0;
}