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;
}
posted @ 2026-10-24 21:27  SgtTree  阅读(11)  评论(0)    收藏  举报