问题描述:今有7对数字:两个1,两个2,两个3,...两个7,把它们排成一行。
要求,两个1间有1个其它数字,两个2间有2个其它数字,以此类推,两个7之间有7个其它数字。如下就是一个符合要求的排列:
要求,两个1间有1个其它数字,两个2间有2个其它数字,以此类推,两个7之间有7个其它数字。如下就是一个符合要求的排列:
17126425374635
问题是写出以74开头的满足条件的序列。
问题分析:根据问题的描述,我们很容易地知道,第7个位置是4,第9个位置是7,任务是将其余的十个数字摆进去。摆放6,2,1的话,只能从第三个开始摆;摆放5,3的话,只能从第四个开始摆(因为位置7,9已被占用)。一个合理的排列是每个数字恰好无重复地排在每个位置上,也就是说,一个位置不能既出现3,又出现5。
那么,我们可以将所有的数字要占用的位置号放进set中,如果set中恰好有14个元素,说明无重复,满足条件;否则必定有部分位置没有放置数字和放置超过1个数字。这里利用了set容器内元素无重复的特性。
值得注意的是,每次循环一遍之后,要将set置空。
代码实现:
#include <iostream>
#include <set>
using namespace std;
int main(){
int a[15]; //存放14位整数的数组
memset(a,0,15*sizeof(int));
a[1] = 7;
a[2] = 4;
a[7] = 4;
a[9] = 7;
set<int> s;
for(int i=3;i<=6;i++){ //表示第一个6摆放的位置
for(int j=4;j<=8;j++){ //表示第一个5摆放的位置
for(int k=4;k<=10;k++){ //表示第一个3摆放的位置
for(int x=3;x<=11;x++){ //表示第一个2摆放的位置
for(int y=3;y<=12;y++){ //表示第一个1摆放的位置
s.insert(1);
s.insert(2);
s.insert(7);
s.insert(9);
s.insert(i);
s.insert(i+7);
s.insert(j);
s.insert(j+6);
s.insert(k);
s.insert(k+4);
s.insert(x);
s.insert(x+3);
s.insert(y);
s.insert(y+2);
if(s.size()==14){
a[i] = a[i+7] = 6;
a[j] = a[j+6] = 5;
a[k] = a[k+4] = 3;
a[x] = a[x+3] = 2;
a[y] = a[y+2] = 1;
for(int i=1;i<=14;i++){
cout<<a[i];
}
cout<<endl;
}
s.clear();
}
}
}
}
}
return 0;
}
结果是:74151643752362