POJ 2718

问题描述:

给一串数,求划分后一个子集以某种排列构成一个数,余下数以某种排列构成另一个数,求这两个数最小的差,注意0开头的处理。

超时问题:一开始是得到一个数列的组合之后再从中间进行切割得到两数,会超时。后来采用的方法是将前面的数在DFS中得到固定,在函数work中对后面(n-n/2)个数进行排列组合。

针对整个数列的dfs排列组合剪枝,若当前搜索的第二个数后面全部补零与第一个数所产生的差值比当前所搜索到的结果还要大,那么就直接返回。这个剪枝就是超时与几十MS的差距
int nums[10]={1,10,100,1000,10000,100000,1000000};

解法一:朴素permutation

#include <iostream>
#include <algorithm>
#include <map>
#include <string>
#include <string.h>
#include <ctype.h>
#include <vector>
#include <math.h>
using namespace std; char s[1000];
int t;
int main()
{
cin>>t;
getchar();
while(t--)
{
int a[11],num=0,ans=0x7f7f7f;
gets(s);
for(int i=0;i<strlen(s);i++)
if (s[i] >= '0'&&s[i] <= '9')//删除空格
a[num++]=s[i]-'0';
sort(a,a+num);
do
{
int num1=0,num2=0;
//前面那个数的首位不能是0,后面那个数的首位也不能是0,还有当为输入是10时,要么前面那个数的是0,要么后面的那个数是0,所以条件num>2加"||"前后都一样
if(!a[0]||(!a[num/2] && num>2))continue;
for(int i=0;i<num/2;i++)num1=num1*10+a[i];
for(int i=num/2;i<num;i++)num2=num2*10+a[i];
ans=min(ans,abs(num1-num2));
}while(next_permutation(a, a+num));
cout<<ans<<endl;
}
return 0;
}

解法二:dfs+permutation

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>//next_permutation包含其中
using namespace std; int a[15], vis[15], n, ans, aa, bb; void solve(int aa) {
int len = 0, flag = 1, b[15];
bb = 0;
for(int i = 0; i < n; i++)
if(!vis[i]) b[len++] = a[i];
for(int i = 0; i < len; i++) {
if(i == 0 && b[i] == 0) flag = 0;
bb = bb * 10 + b[i];
}
if(flag) ans = min(ans, abs(aa-bb));
while(next_permutation(b, b+len)) {
bb = 0;
flag = 1;
for(int i = 0; i < len; i++) {
if(i == 0 && b[i] == 0) flag = 0;
bb = bb * 10 + b[i];
}
if(flag) ans = min(ans, abs(aa-bb));
}
return;
} void dfs(int k, int res) {
if(k == n/2) {
solve(res);
return;
}
for(int i = 0; i < n; i++) {
if(!vis[i]) {
if(a[i] == 0 && k == 0) continue;
vis[i] = 1;
dfs(k+1, res*10+a[i]);
vis[i] = 0;
}
}
return;
} int main() {
int kase;
scanf("%d", &kase);
getchar();
while(kase--) {
n = 0;
char ch;
memset(a, 0, sizeof(a));
memset(vis, 0, sizeof(vis));
while((ch = getchar()) != '\n') {
if(ch == ' ')
continue;
else a[n++] = ch - '0';
}
if(n == 2 && a[0] == 0) { //当只有两个数字,且其中一个为0时,特殊处理
printf("%d\n", a[1]-a[0]);
continue;
}
ans = 1 << 30;
dfs(0, 0);
printf("%d\n", ans);
}
return 0;
}

POJ 2718【permutation】的更多相关文章

  1. POJ 3187【permutation】

    POJ 3187 给定N值,从而确定了数据的范围及长度,暴力枚举数列,接下来类似杨辉三角的递推计算.注permutation从递增有序数列开始枚举,枚举到符合sum值时退出即可 #include &l ...

  2. 【简●解】POJ 1845 【Sumdiv】

    POJ 1845 [Sumdiv] [题目大意] 给定\(A\)和\(B\),求\(A^B\)的所有约数之和,对\(9901\)取模. (对于全部数据,\(0<= A <= B <= ...

  3. POJ 2154 【POLYA】【欧拉】

    前记: TM终于决定以后干啥了.这几天睡的有点多.困饿交加之间喝了好多水.可能是灌脑了. 切记两件事: 1.安心当单身狗 2.顺心码代码 题意: 给你N种颜色的珠子,串一串长度问N的项链,要求旋转之后 ...

  4. POJ 3230 【DP】

    题意: 某货旅行,在n个城市呆m天. 给出从第i个城市到第j个城市的路费,或者留在某个城市的生活费. 给出在第i天在第j个城市的收益. 可以在城市之间任意穿梭逗留没有其他特殊要求. 求收益最大是多少. ...

  5. Tiling POJ 2506 【大数】

    id=2506">http://poj.org/problem?id=2506 Description In how many ways can you tile a 2xn rect ...

  6. poj 2431 【优先队列】

    poj 2431 Description A group of cows grabbed a truck and ventured on an expedition deep into the jun ...

  7. poj 2385【动态规划】

    poj 2385 Apple Catching Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14007   Accepte ...

  8. POJ 1286 【POLYA】

    题意: 给你三种颜色的珠子,每次给你N,问在旋转,翻转之后视作相同的情况下,能组成多少种不同的项链. 思路: 让我们借这道题拯救一下我对POLYA定理的理解... sigma(m^(gcd(i,n)) ...

  9. POJ 3270 【组合数学】

    题意: 给长度为N的学列,然后让你通过置换来使其递增.原序列没有相同的数字. 1 ≤ N ≤ 10,000 ai<=100000 思路: 先找到循环,然后根据贪心只有两种比较好的情况,让循环里边 ...

随机推荐

  1. 编写优秀jQuery插件技巧

    1. 把你的代码全部放在闭包里面 这是我用的最多的一条.但是有时候在闭包外面的方法会不能调用. 不过你的插件的代码只为你自己的插件服务,所以不存在这个问题,你可以把所有的代码都放在闭包里面. 而方法可 ...

  2. STM32固件库下载地址

    http://www.stmcu.org/document/list/index/sort-hot/category-517找标准外设库命名的资源

  3. 20155332 2016-2017-2 《Java程序设计》第5周学习总结

    学号 2016-2017-2 <Java程序设计>第X周学习总结 教材学习内容总结 1.Java中的所有不正常类都继承于Throwable类.Throwable主要包括两个大类,一个是Er ...

  4. HDU1875 畅通工程再续【最小生成树】

    题意: 在这些小岛中建设最小花费的桥,但是一座桥的距离必须在10 -- 1000之间. 思路: 用最小生成树解决吧,就那两个算法. 代码: prim #include <iostream> ...

  5. 出现fonts/fontawesome-webfont.woff?v=4.5.0 net::ERR_ABORTED

    虽然网页正常显示和运行,但是有2个字体文件出现404错误. 原因:服务器没有配置MIME类型而已. 1. 在IIS网站中,找打网站对应的MIME类型,双击. 2.能看到此网站对应的MIME类型,点击右 ...

  6. I - Interesting Calculator (bfs使用优先队列求步数最小或者花费最小)

    题目链接:https://cn.vjudge.net/contest/245287#problem/I 代码: 使用普通的队列和优先队列相比,优先队列能更快地找到目的变量. #include<i ...

  7. js 鼠标拖拽元素

    基础知识 event.clientX.event.clientY 鼠标相对于浏览器窗口可视区域的X,Y坐标(窗口坐标),可视区域不包括工具栏和滚动条.IE事件和标准事件都定义了这2个属性 event. ...

  8. opencv入门指南(转载)

    转载链接:http://blog.csdn.net/morewindows/article/details/8426318 网上的总结的一些用openncv的库来做的事: 下面列出OpenCV入门指南 ...

  9. Linux文件系统2---VFS的四个主要对象

    1.引言 本文所述关于文件管理的系列文章主要是对陈莉君老师所讲述的文件系统管理知识讲座的整理. Linux可以支持不同的文件系统,它源于unix文件系统,也是unix文件系统的一大特色. Linux文 ...

  10. 编写html与js交互网页心得:编写两个按钮切换显示不同的图片

    第一步:先建立一个html网页,如下: <!DOCTYPE html><html> <head>  <meta charset="utf-8&quo ...