东华OJ二维数组中等 数的整除--STL,yyds!

DFS,NO!STL,YES!

问题描述 :

有一次,明明所在的学校举行校数学竞赛,明明一向数学成绩突出,因此作为班级的代表,被派去参赛。

在比赛中,明明遇到了这样一个问题:

“用1到9这9个数字组成3个3位数,9个数字每个都只能用一次,在这种组合中要求第二个和第三个数都能被第一个数整除。现要求求出所有符合条件的这种组合,并对所有的组合进行排序,排序的依据是:首先每组中三个数从小到大进行排序,组与组之间首先比较第一个数,小的在前,若第一个数相同,则比较第二个数,小的在前。”

明明在比赛中对这道题目想了很久,最终还是成功地把这道题给解了出来,明明也因此获得了这次校数学竞赛的第一名。明明回家后,也把这道题目给你做,并且增大了题目的难度,明明不需要你把所有的可能的数字组合写出来,而是他想让你写出第几种组合,你就要写出第几种组合。你作为一名程序设计专家,这样的问题在你看来是小菜一碟,于是就写了一个程序,来解明明的题目。

明明的问题可以归结为:用1到9这9个数字组成3个3位数,9个数字每个都只能用一次,在这种组合中要求第二个和第三个数都能被第一个数整除。现要求求出所有符合条件的这种组合,并对所有的组合进行排序。排序的依据是:首先每组中三个数从小到大进行排序,组与组之间首先比较第一个数,小的在前,若第一个数相同,则比较第二个数,小的在前。排完序后,为这些组合进行编号,第一组编号S1,第二组编号S2,以此类推。现在如果明明要求输出第n个组合,那就输出编号为Sn的那个组合。

输入说明 :

你写的程序要求从标准输入设备(通常,键盘为标准输入设备)中读入测试数据作为你所写程序的输入数据。标准输入设备中有多组测试数据,每组测试数据仅占一行,每行仅有一个正整数(正整数的大小一定小于等于所有组合情况的个数的大小)。每组测试数据与其后一组测试数据之间没有任何空行,第一组测试数据前面以及最后一组测试数据后面也都没有任何空行。

输出说明 :

对于每一组测试数据,你写的程序要求计算出一组相应的运算结果,并将这一组运算结果作为你所写程序的输出数据依次写入到标准输出设备(通常,显示屏为标准输出设备)中。每组运算结果输出所对应的三个数,每个数用一个空格隔开。每组运算结果单独形成一行数据,其行首和行尾都没有任何空格,每组运算结果与其后一组运算结果之间没有任何空行,第一组运算结果前面以及最后一组运算结果后面也都没有任何空行。

Sample Input:

1
2

Sample Output

129 387 645
129 645 387

分解问题:

  1. 读题:第一个就是对于1~9不重复组成的三个三位数的所有情况。是个全排列问题。如果这题枚举的话,反正我的计算机花了20mins也没输出完。明显这是一个需要提前全排列的问题。
  2. 全排列:在STL库里有个很简单的全排列函数next_permutation(array,array+n)。array是数组变量名,n是需要排列的元素个数。使用条件是这个数组是按字典顺序排列的。(不是的可以先排列后再用)这个函数不仅返回全排列后的数组,而且返回一个bool值,表示排列成功或否。所以完美匹配这题。

//注释是心路历程。别把青春插错秧,做题哪有干饭香。

AC代码

#include <bits/stdc++.h>

using namespace std;

int main()
{
   
   
    //.1 .2打表题很多啊。
    //有10s这还不直接暴力求 枚举 都可以举
    //xdm这题不对劲
    //《 坏 了 》
    
### 关于东华大学OJ平台中二维数组从右上到左下遍历的解题思路 对于给定的二维数组,要实现从右上角至左下的遍历方式,通常涉及对角线方向的据访问模式。这种特定路径上的元素处理可以通过调整索引来完成。 在提供的代码片段中,存在一些逻辑用于计算两条特殊对角线上元素乘积与商之和的操作[^1]: ```cpp for(j=0;j<m;j++) { x1=a[j][j]; // 这就是左上到右下的元素值,易找 for(i=0;i<m;i++) { if((m-1)==i+j) { x2=a[i][j];//这是左下到右上的元素 break; } } } ``` 然而,这段代码主要关注的是两个主对角线(即从左上到右下以及从右上到左下),而不是整个矩阵按指定路线遍历的方法。为了真正实现从右上往左下的遍历并获取相应位置的值,可以采用如下方法: #### 方法一:基于行列坐标的转换 通过改变循环结构来适应新的遍历顺序。具体来说,在外层循环控制当前所处的斜率k(即`row + col = const`),内层则迭代满足此条件的所有(row, col)组合。 ```cpp #include <iostream> using namespace std; int main() { int n; cin >> n; // 输入方阵大小n*n int matrix[n][n]; // 填充matrix... for(int k = 0; k < 2 * n - 1; ++k){ for(int row = max(0, k-(n-1)); row <= min(k, n-1); ++row){ int col = k - row; cout << "Element at (" << row << ", " << col << ") is: " << matrix[row][col]<< endl; } } return 0; } ``` 这种方法能够有效地按照从右上向左下的轨迹读取每一个元素,并且适用于任意尺寸的方形矩阵。 #### 方法二:利用辅助据结构存储结果后再输出 另一种策略是创建一个新的列表或其他容器类型用来保存沿所需路径提取出来的元素,最后再统一打印出来。这种方式可能更直观但也稍微增加了空间复杂度。 上述两种方案都可以很好地解决如何在一个二维数组里执行从右上方移动到左下方的任务。选择哪种取决于实际应用场景和个人偏好。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值