P12566 [UOI 2023] An Array and Several More Arrays 题解
P12566 [UOI 2023] An Array and Several More Arrays 题解
题目链接
爆搜练习题。
题意简述
给定
数据范围
题目分析
首先排列内
把这个思路扩展一下,首先将每组数由小到大排序,每次枚举当前排列内最小的一个数由哪一个数组来构成,计算出
具体实现可以用一个 dfs 枚举,也可以用 next_permutation 函数枚举每组可能的排列。注意用 dfs 的时候所有变量都要回溯。
时间复杂度
代码
#include<bits/stdc++.h>
using namespace std;
int n,k;
vector<int> a[10];
int vis[7],ans[7];
int cnt[50005];
bool dfs(int now,int minn){
if(now > k){
return true;
}
for(int i = 1;i<=k;i++){
if(!vis[i]){
vis[i] = 1;
ans[i] = minn-a[i][0];
int flag = 1,min2 = minn;
for(int x:a[i]){
if(cnt[x+ans[i]] || x+ans[i]>n) flag=0;
cnt[x+ans[i]]++;
while(cnt[min2]) min2++;
}
if(flag && dfs(now+1,min2)) return true;
vis[i]=0;
for(int x:a[i]) cnt[x+ans[i]]--;
ans[i]=0;
}
}
return false;
}
int main(){
scanf("%d%d",&n,&k);
for(int i = 1;i<=k;i++){
int x;scanf("%d",&x);
for(int j = 1;j<=x;j++){
int y;scanf("%d",&y);
a[i].push_back(y);
}
sort(a[i].begin(),a[i].end());
}
int res = dfs(1,1);
if(res){
printf("Yes\n");
for(int i = 1;i<=k;i++) printf("%d ",ans[i]);
}else printf("No");
return 0;
}