题解:洛谷 P1200 你的飞碟在这儿
【题目来源】
洛谷:P1200 [USACO1.1] 你的飞碟在这儿 Your Ride Is Here - 洛谷
【题目描述】
众所周知,在每一个彗星后都有一只 UFO。这些 UFO 时常来收集地球上的忠诚支持者。不幸的是,他们的飞碟每次出行都只能带上一组支持者。因此,他们要用一种聪明的方案让这些小组提前知道谁会被彗星带走。他们为每个彗星起了一个名字,通过这些名字来决定这个小组是不是被带走的那个特定的小组(你认为是谁给这些彗星取的名字呢?)。关于如何搭配的细节会在下面告诉你;你的任务是写一个程序,通过小组名和彗星名来决定这个小组是否能被那颗彗星后面的 UFO 带走。
小组名和彗星名都以下列方式转换成一个数字:最终的数字就是名字中所有字母的积,其中 \(A\) 是 \(1\),\(Z\) 是 \(26\)。例如,USACO 小组就是 \(21\times 19\times 1\times 3\times 15 = 17955\)。如果小组的数字 \( mod \ 47\) 等于彗星的数字 \(mod \ 47\),你就得告诉这个小组需要准备好被带走!(记住“\(a\ mod\ b\)”是 \(a\) 除以 \(b\) 的余数,例如 \(34 \ mod \ 10\) 等于 \(4\))
写出一个程序,读入彗星名和小组名并算出用上面的方案能否将两个名字搭配起来,如果能搭配,就输出 GO,否则输出 STAY。小组名和彗星名均是没有空格或标点的一串大写字母(不超过 6 个字母)。
【输入】
第 \(1\) 行:一个长度为 \(11\) 到 \(66\) 的大写字母串,表示彗星的名字。
第 \(2\) 行:一个长度为 \(11\) 到 \(66\) 的大写字母串,表示队伍的名字。
【输出】
无
【输入样例】
COMETQ
HVNGAT
【输出样例】
GO
【核心思想】
-
问题分析:给定彗星名和小组名两个字符串,将每个字符串中所有字母转换为对应数字(\(A=1, B=2, \ldots, Z=26\))后连乘得到两个数值,若两数对 \(47\) 取模结果相等则输出
GO,否则输出STAY。 -
算法选择:
- 字符串遍历 + 字符映射:逐字符读取字符串,利用 ASCII 码偏移将大写字母映射为 \(1 \sim 26\)
- 模运算:连乘过程中或最后对 \(47\) 取模,避免整数溢出
-
关键步骤:
- 初始化:
m1 = 1, m2 = 1,作为连乘的初始值 - 处理彗星名 \(s1\):
- 遍历每个字符
s1[i],计算t = s1[i] - 'A' + 1得到字母对应数字 m1 *= t累乘所有字母值
- 遍历每个字符
- 处理小组名 \(s2\):同上,结果存入
m2 - 取模比较:
m1 % 47 == m2 % 47则输出GO,否则输出STAY
- 初始化:
-
时间/空间复杂度:
- 时间复杂度:\(O(|s1| + |s2|)\),线性遍历两个字符串
- 空间复杂度:\(O(1)\),仅需两个整型变量存储乘积
-
字符串映射的核心思想:
- ASCII 码偏移映射:利用
'A'的 ASCII 值为 \(65\),通过ch - 'A' + 1将 \(A \sim Z\) 映射为 \(1 \sim 26\) - 连乘哈希:将字符串压缩为一个数值特征,通过模 \(47\) 进一步压缩为同余类
- 模运算防溢出:虽然题目保证字符串长度 \(\leq 6\) 且乘积不会溢出
int,但取模操作是哈希类问题的标准做法 - 同余判定:两数模 \(47\) 相等即认为"匹配",这是一种简单的哈希碰撞容忍策略
- 适用于字符串特征提取、简单哈希匹配类问题
- ASCII 码偏移映射:利用
【解题思路】

【算法标签】
入门 #字符串入门
【代码详解】
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s1, s2; // 定义2个字符串
int m1 = 1, m2 = 1; // 因为连乘,所以初始值为1
cin >> s1 >> s2; // 输入s1和s2
for (int i=0; i<s1.length(); i++) { // 遍历s1
int t = s1[i] - 'A' + 1; // 获得每个字符对应的1-26的数字
m1 *= t; // 进行连乘
}
for (int i=0; i<s2.length(); i++) { // 遍历s2
int t = s2[i] - 'A' + 1; // 获得每个字符对应的1-26的数字
m2 *= t; // 进行连乘
}
m1 = m1 % 47; // 分别对两个结果进行取余运算
m2 = m2 % 47;
if (m1 == m2) { // 如果相同则输出GO
cout << "GO";
} else { // 否则输出STAY
cout << "STAY";
}
return 0;
}
【运行结果】
COMETQ
HVNGAT
GO
浙公网安备 33010602011771号