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. CodeChef - AMLEX-Poetic word

    题目链接  Dhinwaji is an acclaimed poet and likes to play with words and letters. He has bought some sti ...

  2. 在windows中停止mysql提示:'服务正在启动或停止中,请稍候片刻后再试一次'

    发现mysql的windows服务异常,准备卸载并重新注册服务,输入: mysqld --remove MySQL 提示: 发现卸载不掉这个服务,于是找到MySQL服务的pid sc queryex ...

  3. windows Zookeeper本地服务化

    ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.它是一个为分布式应用提供一致性服务的软件,提供的功 ...

  4. input单选框多选框时可用的事件

    change(): 当元素的值发生改变时,会发生 change 事件. 该事件仅适用于文本域(text field),以及 textarea 和 select 元素. change() 函数触发 ch ...

  5. 复杂HTML解析

    面对页面解析难题时候,需要注意问题: 1.寻找“打印次页”的链接,或者看看网站有没有HTML样式更友好的移动版(把自己的请求头设置成处于移动设备的状态,然后接收网站移动版). 2.寻找隐藏在JavaS ...

  6. android的五个进程优先级,内存不足时被清理的顺序

    Android操作系统尝试尽可能长时间的保持应用的进程,但当可用内存很低时最终要移走一部分进程.怎样确定那些程序可以运行,那些要被销毁,Android让每一个进程在一个重要级的基础上运行,重要级低的进 ...

  7. 2018-2019-2 网络对抗技术 20165320 Exp3 免杀原理与实践

    ### 2018-2019-2 网络对抗技术 20165320 Exp3 免杀原理与实践 一.实验内容 1.1 正确使用msf编码器(0.5分),msfvenom生成如jar之类的其他文件(0.5分) ...

  8. android aysncTask面试解析

  9. 基于Python的机器学习实战:KNN

    1.KNN原理: 存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一个数据与所属分类的对应关系.输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应 ...

  10. RabbitMQ运行机制

    AMQP中消息的路由过程和Java开发者熟悉的JMS存在一些差别,AMQP中增加了Exchange和Binding的角色,生产者把消息发布到Exchange上,Binding决定发布到Exchange ...