洛谷刷题之P1008

[NOIP1998 普及组] 三连击

题目背景

本题为提交答案题,您可以写程序或手算在本机上算出答案后,直接提交答案文本,也可提交答案生成程序。

题目描述

1,2,…,91, 2, \ldots , 91,2,,9999 个数分成 333 组,分别组成 333 个三位数,且使这 333 个三位数构成 1:2:31 : 2 : 31:2:3 的比例,试求出所有满足条件的 333 个三位数。

输入格式

输出格式

若干行,每行 333 个数字。按照每行第 111 个数字升序排列。

样例 #1

样例输入 #1

样例输出 #1

192 384 576
* * *
...

* * *
(剩余部分不予展示)

提示

NOIP1998 普及组 第一题

分析

直接用全排列做即可

Code

#include <bits/stdc++.h>

using namespace std;

int a[20];

int main()
{
    for (int i = 1; i <= 9; i++)
    {
        a[i] = i;
    }
    do
    {
        int A = a[1] * 100 + a[2] * 10 + a[3];
        int B = a[4] * 100 + a[5] * 10 + a[6];
        int C = a[7] * 100 + a[8] * 10 + a[9];
        if (B % A != 0 || C % A != 0)
        {
            continue;
        }
        if (B / A == 2 && C / A ==3)
        {
            cout << A << " " << B << " " << C << endl;
        }
    } while (next_permutation(a + 1, a + 9 + 1));
    
    
    return 0;
}
<think>好的,我现在需要帮助用户解答关于C++港P1008目的问。首先,我需要回忆一下这个目的具体内容。P1008目通常指的是“三连击”问,也就是找出所有满足1:2:3比例的三位数组合,每个组合中的三个三位数使用的数字不重复且覆盖1到9的所有数字。 首先,用户可能刚接触这道,不太清楚目要求。我需要先明确目目标:找出所有可能的三位数ABC、DEF、GHI,使得ABC:DEF:GHI = 1:2:3,并且这三个数中的每一位数字(1-9)恰好各出现一次,不能重复也不能遗漏。 接下来,用户可能需要了解解思路。我应该先考虑如何生成这样的三位数组合。因为ABC是第一个数,且三个数的比例是1:2:3,所以ABC的范围应该是从123开始,因为更小的数乘以3可能超过三位数。例如,123*3=369,而最大的可能ABC应该是329,因为329*3=987,超过这个数的话,可能四位数或者数字重复。 然后,生成ABC后,计算DEF=ABC*2,GHI=ABC*3。接下来需要检查这三个数的每一位是否都是1-9的数字,并且没有重复。例如,将三个数转换成字符串连接起来,然后检查总长度是否为9,是否有重复字符,是否包含0。 可能的实现步骤包括循环遍历可能的ABC值,生成对应的DEF和GHI,然后检查数字是否符合要求。例如,循环变量i从123到329,每次计算j=i*2,k=i*3。然后将i、j、k转换成字符串,拼接成一个整体字符串,检查是否包含1-9所有数字且不重复。 这里需要注意,如何高效地检查数字是否满足条件。例如,可以将所有数字合并成一个字符串,然后使用一个集合来判断是否有重复,并且长度是否为9,同时排除0的存在。比如,合并后的字符串长度必须是9,且每个字符都是唯一的,且没有‘0’。 另外,可能的优化点包括,i的范围是否需要调整。例如,当i=192时,i*3=576,可能需要检查是否满足条件。或者是否有的i超出这个范围,但实际测试发现,最大的i可能是329,因为329*3=987,再大比如330的话,330*3=990,这时候会有0出现,所以i的上限应该在329左右。 然后,我需要考虑如何将这些逻辑用C++代码实现。例如,使用一个循环,遍历i从123到329。对于每个i,计算j=i*2,k=i*3。然后将这三个数转换为字符串,合并后检查是否符合条件。 在代码实现中,需要注意处理数字转换为字符串时的前导零问,但目中三位数的要求自然不会有前导零。例如,i必须是三位数,所以i的范围是123到333?或者更准确的是,当i=333时,j=666,k=999,但这时候数字可能有重复,比如三个6,所以实际i的范围可能需要更小。 接下来,检查每个数字是否满足条件的逻辑。例如,将三个数合并为一个字符串,然后检查是否每个字符都是唯一的,且包含1-9每个数字一次。例如,可以使用一个数组或集合来统计每个数字出现的次数,确保每个数字恰好出现一次,并且没有0。 可能的错误点包括:在循环中i的范围不正确,或者在转换为字符串时漏掉某些数字,或者在检查条件时逻辑错误。 然后,用户可能需要具体的代码示例。例如,C++代码的大致结构是: for (int i = 123; i <= 329; ++i) { int j = i * 2; int k = i * 3; // 转换为字符串,合并 string s = to_string(i) + to_string(j) + to_string(k); // 检查s是否包含1-9不重复 // 方法:检查长度是否为9,且无'0',且所有字符唯一 if (s.length() != 9) continue; bool valid = true; bool has_zero = false; int cnt[10] = {0}; for (char c : s) { int num = c - '0'; if (num == 0) { has_zero = true; break; } cnt[num]++; if (cnt[num] > 1) { valid = false; break; } } if (!has_zero && valid) { // 输出结果 cout << i << " " << j << " " << k << endl; } } 然后,需要测试这段代码是否正确。例如,当i=192时,j=384,k=576,合并后的数字是192384576,检查是否每个数字1-9都出现一次。是的,所以这个组合是有效的。同样,其他可能的组合如219, 438, 657;273,546,819等是否正确? 此外,用户可能希望知道为什么i的上限是329,因为当i=329时,k=987,而i=333时,k=999,但此时j=666,会有重复的6,所以实际有效的i可能更小。 最后,总结可能的正确解,并给出代码示例,同时提醒用户注意检查数字范围以及重复和0的问。</think>P1008目要求找出所有满足以下条件的三位数组合: **目要求** 找到所有三位数组合 $(ABC, DEF, GHI)$,满足: 1. $ABC : DEF : GHI = 1 : 2 : 3$ 2. 所有数字 $1-9$ 恰好各出现一次,无重复且无遗漏。 --- ### 解思路 1. **范围分析** - $ABC$ 的最小值为 $123$(更小的数可能导致 $GHI = 3 \times ABC$ 超过三位数)。 - $ABC$ 的最大值为 $329$(若 $ABC = 333$,则 $GHI = 999$,但此时数字重复)。 2. **生成候选数** 遍历 $ABC$ 的可能值($123$ 到 $329$),计算 $DEF = 2 \times ABC$ 和 $GHI = 3 \times ABC$。 3. **验证条件** - 将三个数合并为字符串,检查总长度是否为 $9$(保证无重复且覆盖所有位)。 - 验证是否包含 $1-9$ 且无重复或 $0$。 --- ### 代码实现 ```cpp #include <iostream> #include <string> using namespace std; int main() { for (int i = 123; i <= 329; i++) { int j = i * 2; int k = i * 3; string s = to_string(i) + to_string(j) + to_string(k); if (s.size() != 9) continue; // 长度不足9则跳过 bool valid = true; bool has_zero = false; int cnt[10] = {0}; // 统计数字出现次数 for (char c : s) { int num = c - '0'; if (num == 0) { has_zero = true; break; } cnt[num]++; if (cnt[num] > 1) { valid = false; break; } } if (!has_zero && valid) { cout << i << " " << j << " " << k << endl; } } return 0; } ``` --- ### 输出结果 代码运行后会输出以下合法组合: ``` 192 384 576 219 438 657 273 546 819 327 654 981 ``` --- ### 关键点解释 1. **数字范围** 通过限制 $ABC \in [123, 329]$,确保 $DEF$ 和 $GHI$ 均为三位数。 2. **去重与覆盖** 合并字符串后,统计每个数字出现次数,确保 $1-9$ 各出现一次且无 $0$。 3. **效率优化** 直接遍历候选范围,避免穷举所有可能的三位数组合。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值