用maxs[i], mins[i]表示只剩i张卡片时第i张卡片上数字的最大值和最小值,对于题中给出的n, L.可以确定maxs[n] = L,
mins[n] = 1, 则可以推出maxs[n-1] = L - mins[n], mins[n-1] = 1 - maxs[n]以此类推,求出maxs和mins.
题中给出的d是桌上只剩一张卡片时的卡片上的数字,若d < mins[1] || d > maxs[1]则无解。
否则,a = 1 - d, b = L - d.则[a, b]和[mins[2], maxs[2]]两个区间必定有交集.
1.mins[2] <= a <= maxs[2]那么最初第一张卡牌的数字就可以确定为1,那么现在桌上有两张卡片,第二张卡片数字为1 - d.
2. mins[2] <= b <= maxs[2]那么最初第一张卡牌的数字就可以确定为l,那么现在桌上有两张卡片,第二张卡片数字为L- d.
上述两步只要执行满足条件的一步就行,不断重复上述步骤,从而求出第2, 3, 4, ..n张卡牌原来上的数字.
#include <bits/stdc++.h>
#define maxn 105
using namespace std;
typedef long long ll;
int maxs[maxn], mins[maxn], ans[maxn];
int main(){
int n, d, l;
scanf("%d%d%d", &n, &d, &l);
mins[0] = 1;
maxs[0] = l;
for(int i = 1; i < n; i++){
maxs[i] = l - mins[i-1];
mins[i] = 1 - maxs[i-1];
}
if(d > maxs[n-1] || d < mins[n-1]){
puts("-1");
return 0;
}
for(int i = n-1; i >= 1; i--){
int k1 = l - d;
int k2 = 1 - d;
if(k1 >= mins[i-1] && k1 <= maxs[i-1]){
ans[i] = l;
d = k1;
}
else{
ans[i] = 1;
d = k2;
}
if(i == 1)
ans[i-1] = d;
}
printf("%d", ans[n-1]);
for(int i = n-2; i >= 0; i--)
printf(" %d", ans[i]);
puts("");
return 0;
}