132 条题解
- 
  4Randle LV 9 @ 2017-07-09 15:24:07 #include<iostream> 
 #include<algorithm>
 #include<cstdio>
 using namespace std;
 int n,m,a[100001];
 main()
 {
 scanf("%d%d",&n,&m);
 for(int i=1;i<=n;i++)scanf("%d",&a[i]);
 for(int i=1;i<=m;i++)next_permutation(a,a+n+1);
 for(int i=1;i<=n;i++)printf("%d ",a[i]);
 }
- 
  3@ 2017-07-04 09:34:10//离散书上的经典算法,《离散数学及其应用》P436 #include <iostream> #include <algorithm> using namespace std; int main() { std::ios::sync_with_stdio(false); int arr[10005]; int N, M; int j, k, r, s; cin >> N >> M; for(int i = 0; i < N; i++) cin >> arr[i]; while(M--) { j = N - 2; while(arr[j] > arr[j+1]) j--; k = N - 1; while(arr[k] < arr[j]) k--; swap(arr[k], arr[j]); r = N - 1; s = j + 1; while(r > s) { swap(arr[s], arr[r]); r--; s++; } } for(int i = 0; i < N; i++) cout << arr[i] << " "; cout << endl; return 0; }
- 
  1@ 2019-12-10 16:40:29next_permutation这也能叫题解吗? 因为总数很大,使用DFS去求接下来第N个显然会超时,所以这是个数学问题 首先A个数进行全排列总共有A!种方式。 
 因此,进行递归操作,对于倒数第N-1位数,其之后应该有N个数,如果进行全排列就有N!个可能性。
 但如果要让第N-1个数变化。首先因为后N个数是中间一部分的排列,需要先取K次,使得N-1位数进行第一次变化,之后每变化一次,则需要增加N!个数,总计变化P次,当然,最后一次可能并不够N!个,剩下的部分T就是后N个数的第T个全排列。也就是说将输入M分解为 K+P * N! + T,算出各个值即可 问题的思路大致如此。 
- 
  1@ 2017-08-24 21:28:18next_permuration! 
 #include<iostream>
 #include<cmath>
 #include<vector>
 #include<set>
 #include<bitset>
 #include<algorithm>
 #include<string>
 #include<cstring>
 #include<deque>
 #include<ctime>
 #include<queue>
 #define mp make_pair
 using namespace std;
 inline long long stoi(string s){
 long long rt=0;
 for(int i=0;i<s.size();i++) rt=rt*10+s[i]-'0';
 return rt;
 }
 inline string itos(long long x){
 string rt="";
 while(x){
 rt+=(char)(x%10+'0');
 x/=10;
 }
 reverse(rt.begin(),rt.end());
 return rt;
 }
 const int INF=1000000009;
 int a[10005],n,m;
 int main(){
 cin>>n>>m;
 int i,j;
 for(i=0;i<n;i++) cin>>a[i];
 for(i=0;i<m;i++) next_permutation(a,a+n);
 for(i=0;i<n;i++) cout<<a[i]<<' ';
 return 0;
 }
- 
  0@ 2018-08-07 08:08:59#include <bits/stdc++.h> using namespace std; #define FOR(i,n) for (int i=1;i<=n;i++) #define REP(i,a,b) for (int i=a;i<=b;i++) #define pb push_back #define mp make_pair #define ll long long const int N=10000+10; const int inf=0x3f3f3f3f; const ll mod=7654321; const double PI=3.1415926; const double eps=1e-8; int n,m; int a[N]; void next(int a[]) { int pos=1; REP(i,2,n) if (a[i]>a[i-1]) pos=i; if (pos==1) return; int pos2=0; REP(i,pos,n) { if (a[i]>a[pos-1]&&(pos2==0||a[i]<a[pos2])) { pos2=i; } } swap(a[pos2],a[pos-1]); sort(a+pos,a+1+n); /* FOR(i,n) cout<<a[i]<<" "; cout<<endl; */ } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); cin>>n>>m; FOR(i,n) cin>>a[i]; while (m--) next(a); FOR(i,n) cout<<a[i]<<" "; cout<<endl; return 0; }
- 
  0@ 2018-02-06 09:47:51#include<cstdio> #include<algorithm> int a[10010]; int main() { int n, m; scanf("%d%d", &n, &m); for(int i=1; i<=n; i++) scanf("%d", &a[i]); while(m--) std::next_permutation(a+1, a+n+1); for(int i=1; i<n; i++) printf("%d ", a[i]); printf("%d", a[n]); return 0; }
- 
  0@ 2017-07-23 13:51:56!刷题并不重要,重要的是理解! 
 祝大家 RP+++#include <iostream> #include <algorithm> using namespace std; int a[10005], n,m; int main() { ios::sync_with_stdio(false); //iostream 加速开关 cin >> n >> m; //INPUT for(int i=0; i<n; i++) cin >> a[i]; for(; m--;) // 循环m次 next_permutation(a,a+n); // C++STL 下一个排列 for(int i=0; i<n; i++) // OUTPUT cout << a[i] << ' '; cout << endl; }
- 
  0@ 2017-05-08 08:01:39直接调用STL就好啦~ 
 当然要认真地写常规算法也是可以的#include <iostream> #include <algorithm> using namespace std; int n,m,martian[10001]; void print() { for(int i=0;i<n-1;i++) cout<<martian[i]<<' '; cout<<martian[n-1]<<"\n"; } int main() { cin>>n>>m; for(int i=0;i<n;i++) cin>>martian[i]; for(int i=1;i<=m;i++) next_permutation(martian,martian+n); print(); return 0; }
- 
  0@ 2014-08-16 20:33:59var 
 n,k,i,ans:longint;
 a:array[1..10000] of longint;procedure qsort(l,r:longint); 
 var
 i,j,mid,t:longint;
 begin
 i:=l;
 j:=r;
 mid:=a[(l+r) div 2];
 repeat
 while a[i]<mid do inc(i);
 while a[j]>mid do dec(j);
 if i<=j then
 begin
 t:=a[i];
 a[i]:=a[j];
 a[j]:=t;
 inc(i);
 dec(j);
 end;
 until i>j;
 if l<j then qsort(l,j);
 if i<r then qsort(i,r);
 end;procedure try(p:longint); 
 var
 i,k,l,j,t:longint;
 t1:boolean;
 begin
 if ans=0 then
 begin
 for i:=1 to n-1 do
 write(a[i],' ');
 writeln(a[n]);
 halt;
 end;
 for i:=n-1 downto p+1 do
 begin
 t1:=true;
 while t1 do
 begin
 t1:=false;
 l:=maxlongint;
 k:=0;
 for j:=i+1 to n do
 if (a[j]>a[i]) and (a[j]<l) then
 begin
 l:=a[j];
 k:=j;
 end;
 if k<>0 then
 begin
 t:=a[i];
 a[i]:=a[k];
 a[k]:=t;
 t1:=true;
 qsort(i+1,n);
 dec(ans);
 try(i);
 end;
 end;
 end;
 end;begin 
 readln(n);
 readln(k);
 for i:=1 to n do
 read(a[i]);
 ans:=k;
 try(0);
 end.//By Fkc
- 
  0@ 2014-08-15 14:05:54#include<algorithm> 
 #include<iostream>
 using namespace std;
 main()
 {
 int i,n,m,a[10001];
 cin>>n>>m;
 for(i=1;i<=n;i++)
 cin>>a[i];
 for(i=1;i<=m;i++)
 next_permutation(a+1,a+n+1);
 for(i=1;i<=n;i++)
 cout<<a[i]<<' ';
 }
 跟楼下一个方法。
- 
  0@ 2014-08-15 14:02:26#include<iostream> 
 #include<cstdio>
 #include<algorithm>
 using namespace std;
 int n,m,a[10001];
 main()
 {
 cin>>n>>m;
 for (int i=1;i<=n;i++)
 cin>>a[i];
 for (int i=1;i<=m;i++)
 next_permutation(a+1,a+n+1);
 for (int i=1;i<=n;i++)
 cout<<a[i]<<' ';
 }
 algorithm函数库真心强大。连求下一个排列的函数都有。2004T4,15行代码秒杀!next_permutation万岁~
- 
  0@ 2014-07-11 12:27:34var 
 a:array[1..10000]of longint;
 n,m,i,j,k,t,l:longint;
 procedure swap(var a,b:longint);
 var t:longint;
 begin
 t:=a;a:=b;b:=t;
 end;
 procedure quicksoft(l,r:longint);
 var
 x,y,mid:longint;
 begin
 mid:=a[(l+r)div 2];x:=l;y:=r;
 repeat
 while a[x]<mid do inc(x);
 while a[y]>mid do dec(y);
 if x<=y then begin swap(a[x],a[y]);inc(x);dec(y);end;
 until x>y;
 if x<r then quicksoft(x,r);
 if l<y then quicksoft(l,y);
 end;
 begin
 read(n,m);
 for i:=1 to n do read(a[i]);
 for i:=1 to m do
 for j:=n downto 2 do
 if a[j-1]<a[j] then
 begin
 t:=maxlongint;
 for k:=j to n do if (a[k]<t)and (a[k]>a[j-1]) then
 begin t:=a[k];l:=k;end;
 swap(a[j-1],a[l]);
 quicksoft(j,n);
 break;
 end;
 for i:=1 to n do write(a[i],' ');
 end.
- 
  0@ 2014-04-30 21:22:03#include <iostream> 
 #include <algorithm>
 #include <vector>using namespace std; int main() 
 {
 int n,m,temp;
 cin >> n >> m;
 vector<int> p;
 for(int i=0;i<n;i++){
 cin >> temp;
 p.push_back(temp);
 }
 for(int i=0;i<m;i++) next_permutation(p.begin(),p.end());
 vector<int>::iterator j;
 for(j=p.begin();j!=p.end();j++) cout << *j <<" ";
 //cout << "Hello world!" << endl;
 return 0;
 }Orz下面所有的神牛。我什么都不懂,我只知道algorithm里面有个叫作next permutation的东西。。。 
- 
  0@ 2014-01-17 09:41:02var 
 f,g:array[1..10001] of integer;n,m,i,j,k,tt,p,q,c:integer; procedure arraya; 
 begin
 for p:=1 to n-i-1 do
 for q:=p+1 to n-i do
 if g[p]>g[q] then
 begin
 k:=g[p];
 g[p]:=g[q];
 g[q]:=k;
 end;
 end;begin 
 readln(n);
 readln(m);
 for i:=1 to n do read(f[i]);
 tt:=m;
 while tt>0 do
 begin
 for i:=n downto 1 do
 if f[i]<f then break;
 c:=20000;
 for j:=i+1 to n do
 if (f[j]<c) and (f[j]>f[i]) then
 begin c:=f[j]; k:=j; end;
 c:=f[i];
 f[i]:=f[k];
 f[k]:=c;
 for j:=i+1 to n do g[j-i]:=f[j];
 arraya;
 for j:=i+1 to n do f[j]:=g[j-i];
 dec(tt);
 end;
 for i:=1 to n-1 do
 write(f[i],' ');
 writeln(f[n]);
 end.
- 
  0@ 2013-12-28 12:35:51编译成功 测试数据 #0: Accepted, time = 62 ms, mem = 540 KiB, score = 10 
 测试数据 #1: Accepted, time = 15 ms, mem = 540 KiB, score = 10
 测试数据 #2: Accepted, time = 0 ms, mem = 544 KiB, score = 10
 测试数据 #3: Accepted, time = 0 ms, mem = 540 KiB, score = 10
 测试数据 #4: Accepted, time = 0 ms, mem = 540 KiB, score = 10
 测试数据 #5: Accepted, time = 0 ms, mem = 544 KiB, score = 10
 测试数据 #6: Accepted, time = 0 ms, mem = 540 KiB, score = 10
 测试数据 #7: Accepted, time = 0 ms, mem = 540 KiB, score = 10
 测试数据 #8: Accepted, time = 15 ms, mem = 540 KiB, score = 10
 测试数据 #9: Accepted, time = 0 ms, mem = 544 KiB, score = 10
 Accepted, time = 92 ms, mem = 544 KiB, score = 100
- 
  0@ 2013-11-06 08:47:17#include <iostream> 
 #include <algorithm>
 using namespace std;
 #define MAX 10001
 int a[MAX],n,m;void fun() 
 {
 int i,c=0,d=0,min;
 for(i=n;i>1;i--)
 if(a[i-1]<a[i])
 {break; 
 }
 c=i-1;
 int v=1;
 if(i!=n)
 {
 for(;i<=n;i++)
 {
 if(a[c]<a[i] )
 {if(v) 
 {
 min=a[i];
 d=i;
 v=0;
 }
 else if(a[i]<min)
 {
 min=a[i];
 d=i;
 }
 }
 }
 }
 else
 d=n;
 // cout<<"a[c] "<<a[c]<<" a[d]"<<a[d]<<endl;
 int tem=a[c];
 a[c]=a[d];
 a[d]=tem;sort(a+c+1,a+n+1); } 
 int main()
 {
 int i;
 while(cin>>n>>m)
 {
 for(i=1;i<=n;i++)
 cin>>a[i];
 for(i=1;i<=m;i++)
 fun();
 for(i=1;i<n;i++)
 cout<<a[i]<<" ";
 cout<<a[i]<<endl;
 }
 return 0;
 }
- 
  0@ 2013-10-20 21:26:00手动生成1-10000的排列肯定超时,而M才100,我们只要掌握生成任意一个排列的下一个即可; 
 通过自己模拟+2、+3等,就可知排列每次肯定都减少一个最靠近右侧的逆序对,如有A[J-1]《A[J],那A[J-1]一定得更新了,因为不可能不变这个A[J-1]却还可以生成下一个排列(慢慢理解其实很简单)。而代替这个A[J-1]的是什么呢,那肯定也是A[J]-A[N]里面大于A[J-1]且最小的一个A[K];然后对A[J]-A[N]排下序即是下一个排列;
 如1 2 3 5 4,j-1为第3个3,则K为第5个4,交换后为1 2 4 5 3,然后再排序为1 2 4 3 5,这就是下一个排列。
- 
  0@ 2013-09-15 15:08:15我记得去年做这题,根本看不懂。。现在一看这么简单 因为n大,以前是想直接dfs,所以不会做。但是今天又看了看题目,觉得很水。 虽然n这么大,但是m只有100.纯粹模拟n,有很多时间是浪费。 可以直接用生成法。//so easy 生成法的原理: 1、j从最后往前面搜,找到第一个a[j-1]<a[j]. 2、在从a[j]-a[n]中找到一个大于a[j-1]的最小数a[k] 3、swap(a[j-1],a[k]) 4、qsort(j,n),使他们从小到大排序。 这样一个排列就生成,如此做m次后,就是最后的答案! 经过一年的训练,能力增强。冲刺2013NOIp普及组一等! SYF 想看跟详细的题解和程序。点 题解 想一起探讨Oi的孩纸门,可加QQ 841249284 峰哥,写明备注,欢迎所有人! 
- 
  0@ 2013-08-23 08:30:46字典序法编程容易实现,而且求某个排列的下一个排列好使。 方法就是 
 如:2341
 第一步:连续两数,满足左边<右边,并且要最靠右的,这里是34,记左边的下标为u.
 编程的时候从右往左扫描,找到就BREAK.
 第二步:以u位置的数3为准,找最靠右的大于它的数4。
 把3,4互换,得到2431;
 第三步:把u位置后面的数,反序.2341->2431->2413 完毕.[感谢notblack大神提供思路] #include<iostream> 
 using namespace std;
 int main()
 {
 int n,m,i,j,k,l,t,h,a[20001],x;
 cin>>n>>m;
 for(i=1;i<=n;i++)
 cin>>a[i];
 for(i=1;i<=m;i++)
 {
 for(j=n;j>1;j--)
 if(a[j]>a[j-1])
 break;
 h=j-1;
 for(l=n;l>1;l--)
 if(a[l]>a[h])
 break;
 k=a[l];a[l]=a[h];a[h]=k;
 for(x=1;x<=n;x++)
 a[x+n]=a[x];
 for(t=2*n;h+1<=n;h++,t--)
 a[h+1]=a[t];
 }
 for(i=1;i<n;i++)
 cout<<a[i]<<" ";
 cout<<a[n];
 system("pause");
 return 0;
 }
- 
  0@ 2013-04-04 09:59:44这题一开始我想深搜成全排列,看看10000个手指就傻了。楼下那位大牛的题解让我豁然开朗,其实最多只需100次循环了,跟M有关。加油、加油!! 
 var i,j,n,k,m,c,w,t:longint;
 a,b:array[1..10000]of longint;
 procedure swap(var a,b:longint);
 begin
 c:=a;
 a:=b;
 b:=c;
 end;
 begin
 readln(n);
 readln(m);
 for i:=1 to n do read(a[i]);
 for i:=1 to m do begin
 w:=n;while a[w-1]>a[w] do dec(w);
 w:=w-1;
 for j:=n downto w+1 do if a[j]>a[w] then begin
 t:=j;
 break;
 end;
 swap(a[w],a[t]);k:=n;
 for j:=w+1 to n do b[j]:=a[j];
 for j:=w+1 to n do begin
 a[k]:=b[j];
 dec(k);
 end;
 end;
 write(a[1]);
 for i:=2 to n do write(' ',a[i]);writeln;
 end.