求符合给定条件的整数集
PTA 基础编程题集 7-16
题目: 给定不超过6的正整数A,考虑从A开始的连续4个数字。请输出所有由它们组成的无重复数字的3位数。*
输入格式:
输入在一行中给出A。
输出格式:
输出满足条件的的3位数,要求从小到大,每行6个整数。整数间以空格分隔,但行末不能有多余空格。(输出要以升序的方式)
可能有多种解法,这里提供一种方法,以供学习交流,可能没有那么易懂,但起初想到了这个思路,就试着写了一下。
先说思路:
输入一个整数——>得到这个整数的后三位——>存进数组1;
创建另外2个数组,数组2和数组3,内容和数组1相同;
(输出是三位数,不妨利用四则运算得到结果存进数组4,最后直接输出数组4就好了)
数组1 ——> 百位
数组2 ——> 十位
数组3 ——> 个位
数组4 ——> 标记
假设输入为 1,则数组为 1 2 3 4
具体实现来看代码:
//求整数集
//给定不超过6的正整数A,考虑从A开始的连续4个数字。请输出所有由它们组成的无重复数字的3位数。
//考虑的解法:构建三个数组,一个标记的数组
//三个数组分别代表 百位、十位、个位
#include <stdio.h>
#include <stdbool.h>
#define ST 4
#define MAX 100
struct Node{ // 数据数组
int data[ST];
int cnt;
};
struct Mark{ //标记数组
int receive[MAX];
int cnt; //当前位置
};
void init_array(int* p){ //初始化数组
int i;
for(i=0;i<ST;i++){
*(p+i) = 0;
}
}
bool all_mark_one(int* p){ //判断标记数组re_mark 是否全都为1
if(*p==*(p+1)==*(p+2)==*(p+3)==1){ //都为1 ,返回true,否则返回false
return true;
}else{
return false;
}
}
void updata_array(int* p,int num_high){ //更新标记数组,把除了高位的数字以外,mark数组全部更新为 0
int i;
for(i=0;i<ST;i++){
if(i==num_high){
*(p+i) = 1;
}else{
*(p+i) = 0;
}
}
}
int main(void)
{
struct Node data_bai; //百位
struct Node data_shi; //十位
struct Node data_ge; //个位
struct Mark output;
int re_mark[4]={0};
output.cnt = 0;
int i,j,k;
scanf("%d",&data_bai.data[0]); //给第一个位置赋值
data_bai.cnt = 0;
output.cnt = 0;
for(i=1;i<ST;i++){ //后面三个依次 +1
data_bai.data[i] = data_bai.data[i-1] + 1;
}
data_shi = data_bai;
data_ge = data_bai;
for(i=0;i<ST;i++){ //第一位
init_array(re_mark); //初始化标记数组
re_mark[i] = 1; //令当前使用过的位数为 标记 为 1
data_bai.cnt = i;
//output.receive[output.cnt] = 100 * data_bai.data[i]; //相乘
for(j=0;j<ST;j++){
if(re_mark[j]==1){
continue;
}else{
data_shi.cnt = j;
//output.receive[output.cnt] += 10* data_shi.data[data_shi.cnt];
re_mark[j] = 1;
for(k=0;k<ST;k++){
if(re_mark[k]==1){
continue;
}else{
data_ge.cnt = k;
output.receive[output.cnt] = data_bai.data[data_bai.cnt]*100 + data_shi.data[data_shi.cnt]*10 + data_ge.data[data_ge.cnt];
re_mark[k] = 1;
++output.cnt;
if(!all_mark_one(re_mark)){ //如果标记中不全为1 ,则重复循环
continue;
}else if(all_mark_one(re_mark)){ //如果全为 1 ,则一定走完了一个流程,更新数组
updata_array(re_mark,data_bai.cnt); //更新标记数组
break; //跳出当前循环
}
}
}
}
}
re_mark[i] = 0; // i 每次走完一轮,令当前所走的数字由1 转变为 0,然后下一个i为1,腾出re_mark的标记空间
}
for(i=0;i<output.cnt;i++){ //每行6个整数。整数间以空格分隔,但行末不能有多余空格。
printf("%d",output.receive[i]);
if((i+1)%6!=0){
printf(" ");
}else{
if(i==output.cnt-1){
}else{
printf("\n");
}
}
}
}
//输入 2
//结果
234 235 243 245 253 254
324 325 342 345 352 354
423 425 432 435 452 453
523 524 532 534 542 543