POJ 2718 搜索+思维

来源:互联网 发布:明朝 西方 知乎 编辑:程序博客网 时间:2024/04/30 16:10

一道思维细节题,没有什么难点。这种题想到就行,没想到错误找一辈子.../(ㄒoㄒ)/~~


POJ 2718:http://poj.org/problem?id=2718

题意: 给出最多10个不重复的从小到大的个位数, 将它们任意组合为两个数字,不能有前导0。

            求出,所有排列中,两个数的最小差值。


网上很多人都是用new_permution还是什么的STL里的取排列办法直接爆搜。没有尝试也不想尝试。

我的心理进程是:

  两个数的要是差最小,那么他们的最高位肯定是给出的数字中相邻的两个数字。一个为小,一个为大。

  然后,高位较小的数字,后面放最大的数,依次放下去。

            低位较大的数字,后面放最小的数,依次放下去。

           那么它们的差就是最小的。


  比如说:   0 1 2 3 4 5

          那么最小差值肯定在这几个数字之中。

          154      203

          254      301

          352      401

          432      501

          而答案也正是 254 301。

        

         模拟一遍后WA了。想起来没考虑数字为奇数个时。

         于是添加上,当个数为奇数个时,剩下的那个数给小的数字加上。然后求差值

        即  01 2 3 4 5 6  

         就变为了    2654 301

         模拟一遍后WA了。 发现这思路根本就是错的啊!

       因为此时,最小的应该是  1023 654

       也就是,左边为最小的四位数,右边为最大的三位数


        终于开开心心的模拟完。交了一发,WA了...微笑


        要砸电脑了微笑    但是后来发现是细节上,n写成len了.....


       总结一下: 思路就是分为,输入的数字个数为奇数还是偶数。

                            若为奇数,则最小差为     最小多位数-最大低位数

                            若为偶数,则搜索任意两位相邻位为最高最低位,把数字填进去,搜索最小解

                           还要分类讨论一下,如果只有两个数字,就输出他们的差即可。


这题代码就很杂乱无章了。仅仅可借鉴思路:


#include"cstdio"#include"cstring"#include"queue"#include"cmath"#include"iostream"#include"algorithm"using namespace std;#define inf 999999999#define loop(x,y,z) for(x=y;x<z;x++)int pos[10],n;int ans;int book[10];void dfs(int m){    if(m==n-1)return;    if(m==0&&pos[m]==0)    {        dfs(m+1);return;    }    int l=pos[m];    int r=pos[m+1];    book[m]=book[m+1]=1;    int i,j;    int t=n/2;    for(i=0,j=1;j<t;i++)    if(!book[i])    {        book[i]=1;        r=r*10+pos[i];        j++;    }    for(i=n-1,j=1;j<t;i--)    if(!book[i])    {        book[i]=1;        l=l*10+pos[i];        j++;    }    int sum=r-l;    ans=min(ans,sum);    memset(book,0,sizeof book);    dfs(m+1);}void odd_cal(){    int l=0;    int r=0;    if(pos[0]==0)        l=pos[1]*10;    else l=pos[0]*10+pos[1];    int i;    loop(i,2,n/2+1)        l=l*10+pos[i];    for(int j=n-1;j>=i;j--)        r=r*10+pos[j];    ans=min(ans,l-r);}int main(){    int i,T,len;    char str[100];    scanf("%d",&T);getchar();    while(T--)    {        ans=inf;        memset(book,0,sizeof book);        gets(str);        len=strlen(str);        n=0;        loop(i,0,len)        if(str[i]!=' ')            pos[n++]=str[i]-'0';        if(n==2)            ans=abs(pos[0]-pos[1]);        else if(n%2==0)            dfs(0);        else        odd_cal();        printf("%d\n",ans);    }    return 0;}


0 0