hdu6351 Beautiful Now (全排列+循環節)
阿新 • • 發佈:2019-02-20
spa continue bsp min 循環節 ++ 處理 efi 博客
題目傳送門
題意:
給你n和k,你每次能交換n的兩個位,問最多k次後的最小和最大值
思路:
考慮到n到1e9,所以可以用全排列來暴力,但是我們不能全排列之前的數位,
因為n中的位數可能相等,那樣很難計算交換次數,因此我們只能全排列下標
然後我們要怎樣計算每次排列的交換次數,這裏用到了循環節
比如:0 1 2 3 4 然後2和3交換
0 1 3 2 4 那麽a[2]=3;a[3]=2;這裏就存在循環
這裏就可以用來處理次數
代碼:
#include<bits/stdc++.h> using namespaceView Codestd; #define INF 0x3f3f3f3f int T; int n,k; char s[25]; int a[25]; int vis[25]; int len; bool check()//檢查次數 { for(int i=0;i<len;i++) vis[i]=0; int ans=0; for(int i=0;i<len;i++) { if(vis[i]) continue; int cnt=0; while(vis[i]==0) { cnt++; vis[i]=1; i=a[i]; } ans+=cnt-1; if(ans>k) return false; } return true; } int main() { scanf("%d",&T); while(T--) { scanf("%s %d",&s,&k); len=strlen(s); for(int i=0;i<len;i++) a[i]=i; int minn=INF,maxn=0; do{ if(s[a[0]]!=‘0‘&&check())//首位不為0 { int ans=0; for(int i=0;i<len;i++) { ans=ans*10+s[a[i]]-‘0‘; } minn=min(minn,ans); maxn=max(maxn,ans); } }while(next_permutation(a,a+len)); printf("%d %d\n",minn,maxn); } return 0; }
參考博客:https://blog.csdn.net/smilelingling/article/details/81542938
hdu6351 Beautiful Now (全排列+循環節)