您的位置:首页 > Web前端

Smallest Difference (POJ 2718, 穷竭搜索)

2017-11-19 13:37 399 查看
       这个题有两种做法:1.使用next_permutation穷举 2.贪心法

       这道题让我发现了一个问题,执行pow(x,y)这个函数就这么费时间么···

       因为这个题在书中属于穷竭搜索的练习题,这里就不说贪心法怎么做了。解题思路就是排列,然后分成两组数,计算差。其实非常无脑,但是我提交了很多遍都TLE。。。直到我看了一下别人写的代码,发现在将一组数字组合成一个多位数时别人用的方法和我不一样。我一开始使用的是

for(int j=0; j<a; j++){
A += digit[j] * pow(10, a-1-j);
}


       然而别人写的是

for(int j=0; j<i; j++){
sum1 = sum1*10 + digit[j];
}
       如果使用第一种方法,那么即使稍微运用一下贪心的思想,只需搜索两个最终用来做差的数的位数相同(总共数字个数为偶数)和位数相差1(总共数字个数为奇数),也会TLE,于是我打算改用贪心法来做了,并且心中大喊:“说好的穷竭搜索呢?”   然而,如果使用的是第二种方法,真真正正穷竭搜索,一点都不用贪心进行优化也不会TLE···

#include<cstdio>
#include<algorithm>
#include<cmath>

using namespace std;

int N;					//the number of cases
int digit[15];
int n;

int sd()
{
int min = 1e9;
do{
for(int i=1; i<=n/2; i++){
                        int sum1 = 0, sum2 = 0;
if(digit[0] == 0 && i!=1){
//如果第一组的第一个数字为0且第一组数字个数不为1
//此种分法无效
continue;
}
if(digit[i] == 0){
//如果第二组的第一个数字为0,此种分法无效
continue;
}
for(int j=0; j<i; j++){ sum1 = sum1*10 + digit[j]; }
for(int j=i; j<n; j++){
sum2 = sum2*10 + digit[j];
}
int difference = abs(sum1 - sum2);
if(difference < min) min = difference;
}
}while(next_permutation(digit, digit+n));
return min;
}
int main()
{
scanf("%d", &N);
getchar();
while(N--){
n = 0;
char temp;
while(~scanf("%c", &temp)){
if('0'<=temp && temp<='9'){
digit[n++] = temp - '0';
}
if(temp == '\n')
break;
}
printf("%d\n", sd());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM 搜索 poj