做法:
- 题目中给的函数式递归定义的,递归终点是j为min时 f(i,j) = i
- 我们从样例中要规律,发现每个点都有某个确定的周期里面。
- 比如 6 5 8 3 4 1 9 2 7
- 6 ----> 1 1-----> 6 周期为2
- 即函数所表达的也是这个意思
- 接下来就需要抽象了,我们把1~n这几个数字抽象成图中的顶点,每个顶点的出度为1,入度也为1
- 这酱紫我们可以把题目中给的样例中的数字变成图
- 画成图后,如下
- 我们发现这个图中有3个连通块,每个连通块的大小分别为2 ,2 ,5
- 题目中给了我们A = 2,B= 5 ,我们惊奇的发现 2*2 + 5*1 = 9
- 即A*x+B*y = n 相同大小连通块的个数本质上就是不定方程的解
- 这样我们的问题就转换成了利用扩展欧几里得求不定方程的解 ,其中x>=0,y>=0
- 那么怎么构造出来输出呢,我们用最近简单的来思路来实现:
- 比如一个连通块的大小为5,那么我们就1 ---> 2 -----> 3 -----> 4---->5 ---->1
- 我们把前面的1抹掉 2 -----> 3 ----> 4------>5 ---->1 这样构造即可
AC代码:
#include<bits/stdc++.h>
#define IO ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define pb(x) push_back(x)
#define sz(x) (int)(x).size()
#define sc(x) scanf("%d",&x)
#define pr(x) printf("%d\n",x)
#define abs(x) ((x)<0 ? -(x) : x)
#define all(x) x.begin(),x.end()
#define mk(x,y) make_pair(x,y)
#define debug printf("!!!!!!\n")
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const double PI = 4*atan(1.0);
const int maxm = 1e8+5;
const int maxn = 1e4+5;
const int INF = 0x3f3f3f3f;
void solve(){
bool flag = false;
ll n,a,b,x,y;
scanf("%I64d%I64d%I64d",&n,&a,&b);
for(ll i=0;i*a<=n;i++){ //枚举出x和y的非负整数解
ll t = n-a*i;
if(t%b == 0){
x = i;
y = t/b;
flag = true;
break;
}
}
if(!flag){
printf("-1\n");
return;
}
ll now = 1;
for(ll i=1;i<=x;i++){
for(ll j = now+1;j<now+a;j++) printf("%I64d ",j);
printf("%I64d ",now);
now+=a;
}
for(ll i=1;i<=y;i++){
for(ll j=now+1;j<now+b;j++) printf("%I64d ",j);
printf("%I64d ",now);
now+=b;
}
}
int main(){
#ifdef LOCAL_FILE
freopen("in.txt","r",stdin);
#endif // LOCAL_FILE
solve();
return 0;
}