POJ2718 Smallest Difference (暴力搜索+全排列)

来源:互联网 发布:javascript读取html 编辑:程序博客网 时间:2024/05/19 17:59

题目链接:传送门

题意:

给你一个长度为n的数列 ,0<=a[i]<=9;用他们组成两个数

然后使两个数的差最小,求这个数。不能有前导0。

 

分析:

要使差最小肯定要使两个数的长度尽量相等,一个为n/2,另

一个为n-n/2.然后dfs搜一下选的数,然后另一个数用剩下的

数做一个全排列就可以了。

 

代码如下:

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;const int mmax = 999999999;int a[10];bool vis[10];int cnt,ans;void solve(int val){    int tmp = 0;    int b[10];    int tot= 0;    for(int i=0;i<cnt;i++){        if(!vis[i]) b[tot++]=a[i],tmp=tmp*10+a[i];    }    do{        tmp = 0;        for(int i=0;i<tot;i++) tmp=tmp*10+b[i];        if(b[0]!=0||tot==1) ans = min(ans,abs(tmp-val));    }while(next_permutation(b,b+tot));}void dfs(int val,int num){    if(num==cnt/2){        solve(val);        return;    }    for(int i=0;i<cnt;i++){        if(!vis[i]){            if(num==0&&a[i]==0&&cnt>3) continue;            vis[i]=1;            dfs(val*10+a[i],num+1);            vis[i]=0;        }    }}int main(){    int t;    scanf("%d",&t);    getchar();    while(t--){        cnt = 0;        char s[100];        gets(s);        for(int i=0;i<strlen(s);i++)            if(s[i]>='0'&&s[i]<='9') a[cnt++]=s[i]-'0';        memset(vis,0,sizeof(vis));        ans = mmax;        dfs(0,0);        printf("%d\n",ans);    }    return 0;}


 

0 0
原创粉丝点击