题目大意:
让你输入n,m,n为数字的个数,m为数字的位数(数字可以出现前缀零)。然后要求你用一种规定来从新排列每一个数,比如3257按照(3,2,4,1)的规则就变成了5273.(要求每一个数都按照这种规定),其实规定就是数字的位数的全排列。最后要求输出变换后的数字组合中的最大值减去最小值的差值最小。找出这个最小差值。(n,m<=8)
解题思路:
直接用暴力的方法破解这道题目。深搜出全部n!的全排列组合,然后一个一个产生。比较~
吐吐槽:
最初感觉暴力会超时的,因为产生全排列用的时间就是8!,还有每组数字,最坏应该是8*8的时间,所有最后8!*8*8=2580480,超过了200万次,oh,最后还是出乎意料,用了30ms过了,感觉是不是因为这个数据只是一组一组地测试,而不是循环来的。好吧,代码写得挺烂,挺难看的。
代码:
#include
#include
using namespace std;
const int MAX=10;
typedef struct n
{
char nu[MAX];
}N;
int di,n,a[MAX];
char sub[MAX];
N num[MAX],temp1[MAX];
void Sub(char a[],char b[],char c[])//a大于b
{
int lena=strlen(a);
for(int i=0;i=0;j--)//进位
{
if(c[j]<'0')//最多就全部为0
{
c[j]+=10;
c[j-1]--;
}
}
c[lena]='\0';
}
void f1(int visited[],int y)
{
int i,j;
if(y==di+1)//输出函数
{
//开始,全排列
char max[MAX]={"0"},min[MAX]={"99999999"},sub1[MAX];
for(i=1;i<=n;i++)
{
for(j=1;j<=di;j++)
{
temp1[i].nu[j-1]=num[i].nu[a[j]-1];
}
temp1[i].nu[j-1]='\0';
if(strcmp(temp1[i].nu,max)==1)
strcpy(max,temp1[i].nu);
if(strcmp(temp1[i].nu,min)==-1)
strcpy(min,temp1[i].nu);
}
Sub(max,min,sub1);
// cout<>n>>di)
{
memset(sub,0,sizeof(sub));
int i;
char max[MAX]={"0"},min[MAX]={"99999999"};
for(i=1;i<=n;i++)
{
cin>>num[i].nu;
if(strcmp(num[i].nu,max)==1)//大于
strcpy(max,num[i].nu);
if(strcmp(num[i].nu,min)==-1)//小于
strcpy(min,num[i].nu);
}
Sub(max,min,sub);
int l,temp[MAX];
for(l=1;l<=di;l++)//先确定首位的输出
{
memset(temp,0,sizeof(temp));//对于每次的输出给对应的数组初始化
memset(a,0,sizeof(a));
a[1]=l;
temp[l]=1;
// cout<<"ha"<
STL版本,60ms,但是代码复杂度低了好多。。。这里发发平平的。
#include
#include
#include
#include
using namespace std;
int mins,n,k,a[10],last[10];
char str[10][10];
struct s
{
char str1[10];
}na[10];
bool cmp(s c,s d)
{
if(strcmp(c.str1,d.str1)>0)
return true;
return false;
}
void solve()
{
for(int i=0;i