这是一道全排列的题!可以调用库函数!next_permuatio(数组起点,数组终点)!按字典序排列!
全排列next_permutation HDU 1027 PKU 3187 1146 1731
(2009-11-22 11:42:40)
转载
标签:
全排列
杂谈 分类:STL
这个函数可以计算一组数据的全排列
假设数列 d1,d2,d3,d4……
范围由[first,last)标记,调用next_permutation使数列逐次增大,这个递增过程按照字典序。
若当前调用排列到达最大字典序,比如dcba,就返回false,同时重新设置该排列为最小字典序。
返回为true表示生成下一排列成功。
另外,库中另一函数prev_permutation与next_permutation相反,由原排列得到字典序中上一次最近排列。
**********************************************************************************************
几道题目:
1.HDU 1027
求第M个排列,写错一次,数组开头num+1没+1
代码:
#include<stdio.h>
#include<algorithm>
using namespace std;
int main()
{
int n,m,i;
int num[1001];
for(i=1;i<=1000;i++)
num[i]=i;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=0;i<m-1;i++)
next_permutation(num+1,num+n+1);
for(i=1;i<=n;i++)
{
if(i>1) printf(" ");
printf("%d",num[i]);
}
printf("/n");
sort(num+1,num+n+1);
}
return 0;
}
**********************************************************************************************
2.PKU 3187
Backward Digit Sums
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 1653 Accepted: 950
Description
FJ and his cows enjoy playing a mental game. They write down the numbers from 1 to N (1 <= N <= 10) in a certain order and then sum adjacent numbers to produce a new list with one fewer number. They repeat this until only a single number is left. For example, one instance of the game (when N=4) might go like this:
3 1 2 4 4 3 6 7 9 16Behind FJ's back, the cows have started playing a more difficult game, in which they try to determine the starting sequence from only the final total and the number N. Unfortunately, the game is a bit above FJ's mental arithmetic capabilities.
Write a program to help FJ play the game and keep up with the cows.
看这题目的风格似乎是USACO上的题?还没做到,预先过了一题,嘿嘿
生成N的全排列,然后一次计算s[0],与sum相等即为答案!
调试一次,把s[]和m的初始化放到了while(1)的外面,变成死循环
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int main()
{
int n,sum,i,j,m;
int num[11],s[11];
for(i=0;i<10;i++)
num[i]=i+1;
while(scanf("%d%d",&n,&sum)!=EOF)
{
while(1)
{
for(i=0;i<n;i++)
s[i]=num[i];
m=n-1;
while(m!=0)
{
for(j=0;j<m;j++)
s[j]+=s[j+1];
m--;
}
if(s[0]==sum)
break;
next_permutation(num,num+n);
}
for(i=0;i<n;i++)
{
if(i>0) printf(" ");
printf("%d",num[i]);
}
printf("/n");
}
return 0;
}
**********************************************************************************************
PKU 1146
ID Codes
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 2657 Accepted: 1645
简单应用
代码:
#include<stdio.h>
#include<algorithm>
using namespace std;
int main()
{
int len;
char s[51];
while(scanf("%s",s)!=EOF)
{
if(s[0]=='#')
break;
len=strlen(s);
if(next_permutation(s,s+len))
printf("%s/n",s);
else
printf("No Successor/n");
}
return 0;
}
**********************************************************************************************
PKU 1731
Orders
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 4751 Accepted: 3060
输出全排列,一开始打算用prev_permutation回到字典序最小的那个,发现循环停止不了
是不是prev_permutation的返回值跟next的不同呢?解决后再补上
于是改用sort排序,也是一题简单应用
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
bool cmp(char x,char y)
{
return x<y;
}
int main()
{
int len;
char s[201];
while(scanf("%s",s)!=EOF)
{
len=strlen(s);
sort(s,s+len,cmp);
printf("%s/n",s);
while(next_permutation(s,s+len))
printf("%s/n",s);
}
return 0;
}
//HDU 1027 //http://blog.csdn.net/yueashuxia/archive/2010/04/18/5498646.aspx //http://uni.sina.com.cn/c.php?t=blog&k=%C8%AB%C5%C5%C1%D0&ts=bpost&stype=tag #include<cstdio> #include<cstdlib> #include<iostream> #include<algorithm> using namespace std; int a[1010]; int main() { int N,M,i; while(scanf("%d%d",&N,&M)!=EOF) { for(i=1;i<=N;i++) a[i]=i; for(i=1;i<M;i++) next_permutation(a+1,a+N+1); for(i=1;i<=N;i++) { printf("%d",a[i]); if(i!=N) printf(" "); } printf("/n"); } return 0; }