POJ 2718 Smallest Difference(DFS+全排列函数)
2015-09-18 13:17
501 查看
http://poj.org/problem?id=2718
题意: 给从0….9的几个数,让其组成两个整数,保证每个整数没有前导0。求这两个整数的最小差。
思路:开始用爆搜将所有的情况都枚举出来求解,结果没有出乎意料的T了。然后想到 如果要使这两个数的差最小,那么应该让这两个数的数的位数接近相等,只需要DFS(n/2) 层。然后剩下的n/2个数可以用一个全排列函数来列出所有的情况再一一求解即可。
From:http://blog.sina.com.cn/s/blog_9f7ea4390101101u.html
这是一个求一个排序的下一个排列的函数,可以遍历全排列,要包含头文件
下面是以前的笔记 与之完全相反的函数还有prev_permutation。
如果存在a之后的排列,就返回true。如果a是最后一个排列没有后继,返回false,每执行一次,a就变成它的后继。
输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
如果改成 while(next_permutation(a,a+2));
则输出:
1 2 3
2 1 3
只对前两个元素进行字典排序
显然,如果改成 while(next_permutation(a,a+1)); 则只输出:1 2 3
若排列本来就是最大的了没有后继,则next_permutation执行后,会对排列进行字典升序排序,相当于循环
int list[3]={3,2,1};
next_permutation(list,list+3);
cout<< list[0]<< ” “<< list[1]<<” “<< list[2]<< endl;
//输出: 1 2 3
这样就不必事先知道ch的大小了,是把整个ch字符串全都进行排序
若采用 while(next_permutation(ch,ch+5)); 如果只输入1562,就会产生错误,因为ch中第五个元素指向未知
若要整个字符串进行排序,参数5指的是数组的长度,不含结束符
- next_permutation 自定义比较函数
好了科普完毕,贴AC代码:
题意: 给从0….9的几个数,让其组成两个整数,保证每个整数没有前导0。求这两个整数的最小差。
思路:开始用爆搜将所有的情况都枚举出来求解,结果没有出乎意料的T了。然后想到 如果要使这两个数的差最小,那么应该让这两个数的数的位数接近相等,只需要DFS(n/2) 层。然后剩下的n/2个数可以用一个全排列函数来列出所有的情况再一一求解即可。
From:http://blog.sina.com.cn/s/blog_9f7ea4390101101u.html
这是一个求一个排序的下一个排列的函数,可以遍历全排列,要包含头文件
下面是以前的笔记 与之完全相反的函数还有prev_permutation。
(1) int 类型的next_permutation
[code]int main() { int a[3]; a[0]=1;a[1]=2;a[2]=3; do{ cout<< a[0]<< " "<< a[1]<<" "<< a[2]<< endl; }while (next_permutation(a,a+3)); //参数3指的是要进行排列的长度
如果存在a之后的排列,就返回true。如果a是最后一个排列没有后继,返回false,每执行一次,a就变成它的后继。
输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
如果改成 while(next_permutation(a,a+2));
则输出:
1 2 3
2 1 3
只对前两个元素进行字典排序
显然,如果改成 while(next_permutation(a,a+1)); 则只输出:1 2 3
若排列本来就是最大的了没有后继,则next_permutation执行后,会对排列进行字典升序排序,相当于循环
int list[3]={3,2,1};
next_permutation(list,list+3);
cout<< list[0]<< ” “<< list[1]<<” “<< list[2]<< endl;
//输出: 1 2 3
(2) char 类型的next_permutation
[code]int main() { char ch[205]; cin >> ch; sort(ch, ch + strlen(ch) ); //该语句对输入的数组进行字典升序排序。如输入9874563102 cout<<ch; 将输出0123456789,这样就能输出全排列了 char *first = ch; char *last = ch + strlen(ch); do { cout<< ch << endl; }while(next_permutation(first, last)); return 0; }
这样就不必事先知道ch的大小了,是把整个ch字符串全都进行排序
若采用 while(next_permutation(ch,ch+5)); 如果只输入1562,就会产生错误,因为ch中第五个元素指向未知
若要整个字符串进行排序,参数5指的是数组的长度,不含结束符
(3) string 类型的next_permutation
[code]int main() { string line; while(cin>>line&&line!="#") { if(next_permutation(line.begin(),line.end())) //从当前输入位置开始 cout<<line<<endl; else cout<<"Nosuccesor\n"; } } int main() { string line; while(cin>>line&&line!="#") { sort(line.begin(),line.end());//全排列 cout<<line<<endl; while(next_permutation(line.begin(),line.end())) cout<<line<<endl; } }
- next_permutation 自定义比较函数
[code]#include<iostream> //poj 1256 Anagram #include<string> #include<algorithm> using namespace std; int cmp(char a,char b) //'A'<'a'<'B'<'b'<...<'Z'<'z'. { if(tolower(a)!=tolower(b)) return tolower(a)<tolower(b); else return a<b; } int main() { char ch[20]; int n; cin>>n; while(n--) { scanf("%s",ch); sort(ch,ch+strlen(ch),cmp); do { printf("%s\n",ch); }while(next_permutation(ch,ch+strlen(ch),cmp)); } return 0; }
好了科普完毕,贴AC代码:
[code]#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <math.h> using namespace std; const int N = 15; const int INF = 0x3f3f3f3f; int arr ; int t; bool vis ; void getnum() { memset(arr,0,sizeof(arr)); t=0; char s ; gets(s); for(int i=0;s[i];i++) { if(s[i]>='0' && s[i]<='9') arr[t++] = s[i]-'0'; } return; } int ans; void solve(int a) { int tmp ; int tt=0; for(int i=0;i<t;i++) { if(vis[i]) tmp[tt++] = arr[i]; } do{ if(tmp[0]==0) continue; int now=0; for(int i=0;i<tt;i++) now = now*10+ tmp[i]; ans = min(ans,abs(a-now)); }while(next_permutation(tmp,tmp+tt)); return; } void dfs(int a,int x) { if(x==t/2) { solve(a); return; } for(int i=0;i<t;i++) { if(!vis[i]) continue; if(a==0 && arr[i]==0) continue; vis[i] = false; dfs(a*10+arr[i],x+1); vis[i] = true; } return; } int main() { int T; scanf("%d\n",&T); while(T--) { getnum(); if(t==2) { printf("%d\n",abs(arr[0]-arr[1])); continue; } ans = INF; memset(vis,true,sizeof(vis)); dfs(0,0); printf("%d\n",ans); } return 0; }
相关文章推荐
- js数组操作
- JS 多维度星级评论
- [LeetCode 279] Perfect Squares
- 链接上的CSS应用
- django搭建Bootstrap常用问题解决方法
- JSP 生成静态HTML页面
- 基础的JavaScript编码规范
- In SQL, what’s the difference between a full join and an inner join?
- json-simple简明教程
- event.x,event.clientX,event.offsetX区别
- [CSS]学习总结
- In SQL, what is the difference between a left join and a left outer join?
- Delete Node in a Linked List
- 2015年9月17日第一节课html1-1
- JS+CSS实现TreeMenu二级树形菜单完整实例
- CommonJS规范和Nodejs模块机制
- LeetCode---Delete Node in a Linked List
- toString,一个自动调用的方法
- AngularJS中ng-if/ng-switch时找不到scope下的定义的变量
- Jquery时间格式化,计算时间差