(DFS全排列)POJ-2718 Smallest Difference
Posted 惜取少年时
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(DFS全排列)POJ-2718 Smallest Difference相关的知识,希望对你有一定的参考价值。
简要题意:
给若干组数字,每组数据是递增的在0——9之间的数,且每组数的个数不确定。对于每组数,输出由这些数组成的两个数的差的绝对值最小是多少(每个数出现且只出现一次)。
思路分析:
对于n个数,必定为分成两个位数分别为n/2和n-n/2的数时才可能取得差的绝对值最小。两组数分别进行全排列比较大小,这样比较次数最大为(10A5)*(5A5)=10!,在可以接受的范围内。
参考代码:
1 #include<stdio.h> 2 #include<cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 typedef long long ll; 7 const int INF=0x3f3f3f3f; 8 int a[12],t,n,ans,b[12]; 9 bool vi[12]; 10 void check(int x) 11 { 12 int len=0,y=0,i; 13 for(i=0;i<n;i++) 14 { 15 if(!vi[i]) 16 b[len++]=a[i],y=y*10+a[i]; 17 } 18 if(b[0]!=0||len==1)//如果只有1位的话首位(也就是唯一的那一位)可以为0 19 ans=min(ans,abs(x-y)); 20 while(next_permutation(b,b+len))//全排列借用next_permutation函数 21 { 22 y=0; 23 for(i=0;i<len;i++) 24 { 25 y=y*10+b[i]; 26 } 27 if(b[0]!=0||len==1) 28 ans=min(ans,abs(x-y)); 29 } 30 } 31 void dfs(int k,int an) 32 { 33 34 if(k==n/2) 35 { 36 check(an); 37 return; 38 } 39 else 40 { 41 int i; 42 for(i=0;i<n;i++) 43 { 44 if(!vi[i]) 45 { 46 if(a[i]==0&&k==0&&n>3)//只有一位且此时为0的情况 47 continue; 48 vi[i]=true; 49 dfs(k+1,an*10+a[i]); 50 vi[i]=false; 51 } 52 } 53 } 54 } 55 int main() 56 { 57 char tem; 58 while(~scanf("%d ",&t))//%d后面加上空格可以不用再额外getchar读去换行符 59 { 60 while(t--) 61 { 62 n=0; 63 while((tem=getchar())!=‘\n‘)//注意读入的方法 64 { 65 if(tem==‘ ‘) 66 continue; 67 a[n++]=tem-‘0‘; 68 } 69 ans=INF; 70 memset(vi,false,sizeof(vi)); 71 dfs(0,0); 72 printf("%d\n",ans); 73 } 74 } 75 return 0; 76 }
以上是关于(DFS全排列)POJ-2718 Smallest Difference的主要内容,如果未能解决你的问题,请参考以下文章
Smallest Difference POJ 2718(搜索)