AT_abc367_C 题解
题意
给定两个正整数 \(n\)、\(k\) 和一个长为 \(n\) 的序列 \(R\) ,要求你构造出所有可行的序列 \(A\) ,使其满足: \(1 \leq A_i \leq R_i\),\(\forall i \in [1,n]\) ,且 \(k | \sum_{i=1}^n a_i\) 。按照字典序输出所有可行序列。
做法
爆搜解决一切!
用 dfs(now,x,sum,ans[]) 表示搜索状态,四个参数分别表示当前搜到了第 \(now\) 个位置,当前位置上填充的数是 \(x\) ,总和是 \(sum\) ,以及填充到的数组 \(ans[]\) 。
对于每个位置我们从 \(1\) 到 \(R_i\) 枚举填充的数,每次层数到达 \(n\) 后表示当前序列已填充完成,判断一下总和是否能被 \(k\) 整除。如果可以就输出。
由于我们枚举的顺序是从小到大的,所以可以保证求出的顺序一定是字典序。
代码
#include<bits/stdc++.h>
typedef long long int ll;
using namespace std;
const int maxn=15;
int n,k,limit[maxn];
int ans[maxn];
void dfs(int now,int x,int sum,int ans[]){
// for(int i=1;i<=n;i++)cout<<"---> "<<ans[i]<<" ";
// cout<<"\n sum : "<<sum<<"\n";
if(now==n){
if(sum%k==0){
for(int i=1;i<=n;i++)cout<<ans[i]<<" ";
cout<<"\n";
}
return;
}
for(int i=1;i<=limit[now+1];i++){
ans[now+1]=i;
dfs(now+1,i,sum+i,ans);
}
}
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++)cin>>limit[i];
for(int i=1;i<=limit[1];i++){
ans[1]=i;
dfs(1,i,i,ans);
}
return 0;
}

浙公网安备 33010602011771号