题目描述:
比如:n数字,分成两行,前面的数字比后面的数大,同一列上的第二行的比第一行同一列的大。列出所有的结果呀
如4个数字 1 2 3
4 5 6
比如:n数字,分成两行,前面的数字比后面的数大,同一列上的第二行的比第一行同一列的大。列出所有的结果呀
如4个数字 1 2 3
4 5 6
一下我自己写的一种方法不知道对不对,有什么不对的,大家提出来呀
//======================================================================
//
// Copyright (C) 2007-2012 三月软件工作室
// All rights reserved
//
// filename :main
// description :思路:根据题意,可以分为两行进行操作,第一行和第二行分为升序,但是两行在一起没有顺序关系,
// 但是同一列上的两个数,第一行的要小于第二行,将最后一个数赋值为最大值,然后将同一列第一行位置的元素即count/2-1的
// 位置赋值为剩下最大的数,然后进行倒数第二列第二进行放剩下的最大值,然后是倒数第二列中第二行放剩下的
// 最大值,一次到底一行,以上是当当前位置没有赋值的时候,如果当前位置,已经赋过值,则将当前位置元素的值,
// 替换成比当前元素小的最大数,如果无法找到对应的数,将当前位置清空,如果是第一行,则重新计算同列第二行上的数据
// ,如果是第二行,那么本列没有符合要求额序列,回下前一个序列,如果找到合适的数字,但是第一行的比第二行大,那么
// 找到一个比当前数小的剩下的最大数,从新按以上规则计算呀
//
// created by Renji at 2012-4-11
// qq:625246906
// url:http://www.marchsoft.cn/
//
//======================================================================
#include <stdio.h>
#include <string.h>
#define MAX 255
int num[MAX];
int list[MAX];
/*
Find a number less than n in the array num
And the number is the largest number less than n;
int len is the length of the array
int count is use num;
*/
///<summary>
///获取下一个能使用的位置,也就是找到一个比n小的在num数组中最的一个数
///</summary>
///<paramname="n"> 当前已经排好的数据中最小的一个</param>
///<paramname="len">num 数组的长度</param>
///<returns>-1没有合适的数据,其他的是1-n的</returns>
int Get_Next_Index(int n,int len)
{
int i,j;
int bl =0;
char f=0;
//遍历所有的数据,找到一个当前数的位置。从大到小判断,
//这样下一个没有出现的数组,就是没有使用数组的最大数。
for(i=len-1;i>=0;i--)
{
if(bl)
{
f=1;
//判断当前数是否在已经使用了
for(j=0;j<len;j++)
{
if(num[i]==list[j])f=0;
}
if(f)return i;
}
if(n==num[i])
bl=1;
}
return -1;
}
int main()
{
int count ;// 数据的个数
int i,j;//循环变量
int tmp;//排序的时候做交换变量和当前位置填充的下标
int col;//当前正在操作的行,从1开始到count/2
int loc;//下一个填充数在num数组的位置,
int result=0;//保存所有的结果数据
char bl=1;//表示是否在判断第一行中的数据,1第一行0第二行
int n;//当前位置的数据
//清空数据
memset(list,0,sizeof(int)*MAX);
scanf("%d",&count);
if(0 != count%2){printf("error\n");return 0;}
for(i=0;i<count;i++)
{
num[i]=i+1;
//scanf("%d",&num[i]);
}
col = count /2;
/*
//排序这样方便使用Get_Next_Index函数找到下一个填充数据的位置
for(i=0;i<count;i++)
{
for(j=i+1;j<count;j++)
{
if(num[i]>num[j])
{
tmp=num[i];
num[i]=num[j];
num[j]=tmp;
}
}
}
*/
//将最后一个赋最大值的
list[count-1]=num[count-1];
while(col>0 && col <= count/2)
{
if(bl)
{
tmp = col -1;
//计算当前坐标。如果当前坐标是第一行的最后一列,并且list中第一行最后一个元素值
//为0,那么n的值为所有最后一个元素的值
//当条件不满足的时候如果当前位置的值为零则让n=下一个元素的为值
//当条件不满足的时候如果当前位置的值不为零则让n=当前位置元素的值
if(count/2 == col && 0 == list[count/2-1] )
{
n = list[count-1];
}
else
if(0 == list[tmp] ) n = list[col ];
else n = list[tmp];
}
else
{
//计算当前列在第二行的位置
tmp = col + count/2-1;
//当条件不满足的时候如果当前位置的值为零则让n=下一个元素的为值
//当条件不满足的时候如果当前位置的值不为零则让n=当前位置元素的值
if(0 == list[tmp] ) n = list[tmp+1];
else n = list[tmp];
}
loc = Get_Next_Index(n,count);
//判断是否找到合法的数据
if( -1 != loc )
{
list[tmp] = num[loc];
if(bl)
{
//判断当前列上第一行的数据大于第二行,则从新对第一行当前列上的从新
//赋值,也就是找一个比当前数小的最大数
if( list[col-1] > list[ col + count/2 -1] )
continue ;
if(1 == col)
{
//当col=1时候表示已经找到一个合适的序列了,输出结果
result++;
printf("%d\n",result);
for(i=0;i<count;i++)
{
if(i==count/2)printf("\n");
printf("%-4d",list[i]);
}
printf("\n");
bl = 0;
}
else
col --;//本列已经得到合适的序列,匹配下一列
}
bl = !bl;//变换操作的行
}
else
{
//没有找到合适序列,清除指定位置的值,变换操作的行,回到上一个位置
if(bl)
{
list[col-1]=0;
bl = 0 ;
continue ;
}
else
{
//表示当前列无法找到合适序列,返回上一列,
bl =1;
list[col + count/2-1] =0;
col++;
continue ;
}
}
}
return 0 ;