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. Mac下MySQL与MySQLWorkbench的安装

    通过查阅各种各样的资料,去安装这些东东.最后经过一番周折终于安装完成.下面是对安装过程和遇到的问题做个简单记录. 一. 下载MySQL和MySQL Workbench http://dev.mysql ...

  2. 【BZOJ】1443: [JSOI2009]游戏Game

    [算法]博弈论+二分图匹配(最大流) [题解]方格图黑白染色得到二分图, 二分图博弈:当起点不属于某个最大匹配时,后手必胜. 问题转化为那些点不属于某个最大匹配. 先找到一个最大匹配,非匹配点加入答案 ...

  3. Linq 中的 in 与 not in 的使用

    接 触 LINQ 也有很长的一段时间了,有些在 SQL 语句中用的很顺手的东西在 Linq 中却不知道如何实现了,最近遇到了一个问题,在 LINQ 的 Where 条件式中要如何使用 IN 与 NOT ...

  4. C# 批量修改文件名

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  5. luogu P1344 [USACO4.4]追查坏牛奶Pollutant Control

    传送门 要求断掉某些边使得两个点不连通,显然是最小割 但是要求选的边数尽量少,,, 可以考虑修改边权(容量),即把边权\(c\)改成\(c*(m+1)+1\) 没了 // luogu-judger-e ...

  6. luogu P3243 [HNOI2015]菜肴制作

    这题一看就知道和拓扑序有关 考虑拓扑排序的时候每次取队列里最小的数进行排序 然后就\(\mathcal{GG}\)了,因为这样只能使字典序最小,而并不能保证题目中要求的每个编号的数要在满足前面数尽量在 ...

  7. 复习python

    1当命令行键入python a.py的方式运行python程序时候,a.py不需要执行权,当已./a.py运行时,需要执行权 2.与c语言不同的地方 i = 3 print (i)#合法 #在pyth ...

  8. es集群数据库~基本安装

    1 安装java环境   yum -y install java-1.8.0-openjdk*->需要最新的JDK环境1.82 安装 es   curl -L -O https://artifa ...

  9. 不修改加密文件名的勒索软件TeslaCrypt 4.0

    不修改加密文件名的勒索软件TeslaCrypt 4.0 安天安全研究与应急处理中心(Antiy CERT)近期发现勒索软件TeslaCrypt的最新变种TeslaCrypt 4.0,它具有多种特性,例 ...

  10. 【CXF】com.sun.xml.internal.ws.fault.ServerSOAPFaultException: Client received SOAP Faul

    在客户端生成代码之后测试出现错误: com.sun.xml.internal.ws.fault.ServerSOAPFaultException: Client received SOAP Faul ...