LuoguP1088 火星人

寫在前面

\(STL\)當然好,但記不住的人(好比我這種cb),就用了其餘解法ide

進制數idea

Idea

連接spa

咱們如何思考呢?code

對於第\(i\)根手指,有\(n-i+1\)種選擇,因而這一位數是\(n-i+1\)進制的blog

咱們的過程分爲三步get

  1. 將火星數變爲進制數
  2. 進制數\(+m\)
  3. 把進制數在轉回火星數

咱們舉個栗子:樣例io

將1,2,3,4,5變爲進制數class

  • 首位1是5種選擇\(\{1,2,3,4,5\}\)的第1種,故變爲0(從0開始)
  • 次位2是4種選擇\(\{2,3,4,5\}\)的第1種,故變爲0
  • 中間位3是3種選擇\(\{3,4,5\}\)的第1種,故變爲0
  • 次低位4是2種選擇\(\{4,5\}\)的第1種,故變爲0
  • 末位5是1種選擇的\(\{5\}\)第1種,故變爲0
  • 最後,1,2,3,4,5變成了\((00000)_{unknown}\)

其中對於每一位,都是\(n-i+1\)進制的數。im

因而,\((00000)_{unknown}+3=(00110)_{unknown}\)next

001.jpg

(寫的很醜,請不要在乎)

再轉化回來

  • 首位0表示這位應選擇${1,2,3,4,5}$4第1種,即1
  • 次位0表示這位應選擇\(\{2,3,4,5\}\)第1種(1被選過了),即2
  • 中間位1表示這位應選擇\(\{3,4,5\}\)第2種,即4
  • 次低位1表示這位應選擇\(\{3,5\}\)第2種,即5
  • 末位0表示這位應選擇\(\{3\}\)第1種,即3
  • 因此本題答案爲「14523」+3=「14253」

因此,代碼獻上。也包括next_permutation的寫法

Code

int a[maxn];
bool vis[maxn];
int n,m;
int main(){
    n=read(); m=read();
    for(int i=1;i<=n;i++){
        a[i]=read();
        int x=a[i];
        for(int j=1;j<=a[i];j++) x-=vis[j];
        vis[a[i]]=1;
        a[i]=x-1;
    }
    a[n]+=m;
    for(int i=n;i;i--){
        a[i-1]+=a[i]/(n-i+1);
        a[i]%=n-i+1; 
    }
    mem(vis,0);
    for(int i=1;i<=n;i++){
        for(int j=0;j<=a[i];j++)
        if(vis[j]) a[i]++;
        printf("%d ",a[i]+1);
        vis[a[i]]=1; 
    }
    return 0;
}
int a[maxn];
int main(){
    int n=read(),m=read();
    for(int i=1;i<=n;i++) a[i]=read();
    while(m--) next_permutation(a+1,a+n+1);
    for(int i=1;i<n;i++) printf("%d ",a[i]);
    printf("%d\n",a[n]);
    
    return 0;
}

\[ The \quad End \]

\[ \text{若男孩笑了哭了累了,說要去流浪;留下大人的模樣,看歲月劍拔弩張.總會有我的成爲你的遠方。-《牧馬城市》毛不易} \]

相關文章
相關標籤/搜索