題目傳送門
思路
老樣子,先看資料範圍。
- \(2 \leq N \leq 12\)
- \(10N - 9 \leq M \leq 10N\)
加上限時五秒鐘,所以可以放心的寫。
設 \(X\) 為輸出的倒數第 \(Y\) 個數,\(Z\) 為上一個數的值。
觀察樣例,確定 \(X\) 的取值範圍是 \((Z+10) \sim (M-Y \times 10+10)\) 這樣我們就可以用遞迴來寫這道題了。
按照題目要求,先統計數量。
首先,按照先前求出來的範圍列舉每個位置上的值。
每一個數字至少要比前一個大 10 ,當它統計出來的數字已經大於了它所限制的最大值,就提前返回。
如果它的每一個位置上都填上了值,並且最後一位的值滿足題目搜給的要求,就統計。
void qq1(int x,int y)
{
if(y>m)
return ;
if(x==0)
{
s++;
return ;
}
for(int i=y+10;i<=m-x*10+10;i++)
qq1(x-1,i);
}
然後按照同樣的方法再遞迴一次。
但是如果它的每一個位置上都填上了值,並且最後一位的值滿足題目搜給的要求,不再統計,直接輸出。
void qq(int x,int y)
{
if(y>m)
return ;
if(x==0)
{
for(int i=n;i>=1;i--)
cout<<h[i]<<" ";
cout<<endl;
return ;
}
for(int i=y+10;i<=m-x*10+10;i++)
{
h[x]=i;
qq(x-1,i);
}
}
程式碼
#include<bits/stdc++.h>
using namespace std;
int n,m;
int h[20];
int s=0;
void qq1(int x,int y)
{
if(y>m)
return ;
if(x==0)
{
s++;
return ;
}
for(int i=y+10;i<=m-x*10+10;i++)
qq1(x-1,i);
}
void qq(int x,int y)
{
if(y>m)
return ;
if(x==0)
{
for(int i=n;i>=1;i--)
cout<<h[i]<<" ";
cout<<endl;
return ;
}
for(int i=y+10;i<=m-x*10+10;i++)
{
h[x]=i;
qq(x-1,i);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(),cout.tie();
cin>>n>>m;
qq1(n,-9);
cout<<s<<endl;
qq(n,-9);
}