[CF1054C]Candies Distribution

题目:Candies Distribution 

传送门:http://codeforces.com/problemset/problem/1054/C

分析:

方法一:

1)类似拓扑排序的做法。

2)当$L_i,R_i$均为$0$时,这个数就是当前最大的数,可以移除并且去掉他带来的影响,即左边的$R_i$减一,右边得$L_i$减一。

3)当$L_i,R_i$均为$0$时,就当这个点入度为$0$,移除影响就相当于去掉与其相邻的边。

#include <bits/stdc++.h>
using namespace std;
const int maxN=1005;
vector<int> tp;
int n,L[maxN],R[maxN],val[maxN];
int main() {
    scanf("%d",&n);
    for(int i=1;i<=n;++i)scanf("%d",L+i);
    for(int i=1;i<=n;++i)scanf("%d",R+i);
    int tn=n;
    for(;;){
        tp.clear();
        for(int i=1;i<=n;++i)
            if(!L[i] && !R[i]){tp.push_back(i);val[i]=tn;L[i]=R[i]=-1;}
        if(tp.size()==0)break;
        tn-=tp.size();
        for(auto it:tp){
            for(int i=1;i<it;++i)--R[i];
            for(int i=it+1;i<=n;++i)--L[i];
        }
    }
    if(tn)puts("NO");
    else{
        puts("YES");
        for (int i=1;i<=n;++i)printf("%d ", val[i]);
    }
    return 0;
}

方法二:

学到了一种神奇的构造。

4)如果这个序列是存在,第$i$个小朋友分糖数为$ n-(L_i-R_i) $必然是不会冲突的,检查这个序列,判断是否满足题意。

5)这道题事实上在询问有多少小朋友糖比自己多,无论最终分糖方案是什么,得到相同糖的小朋友的分组是一样的。

扫描二维码关注公众号,回复: 5211795 查看本文章
#include<bits/stdc++.h>
using namespace std;
const int N = 1005;
int L[N],R[N],res[N];
int main(){
    int n;scanf("%d",&n);
    for(int i=1;i<=n;++i)scanf("%d",L+i);
    for(int i=1;i<=n;++i)scanf("%d",R+i);
    for(int i=1;i<=n;++i)res[i]=n-L[i]-R[i];
    for(int i=1;i<=n;++i)
        for(int j=i+1;j<=n;++j){
            R[i]-=res[j]>res[i];
            L[j]-=res[j]<res[i];
        }
    for(int i=1;i<=n;++i)
        if(L[i]||R[i]){puts("NO");return 0;}
    puts("YES");
    for(int i=1;i<=n;++i)printf("%d ",res[i]);
    return 0;
}

如果保证有合法解,求一种可行解,然后范围又极大,可以用第二种方法直接构造呀

猜你喜欢

转载自www.cnblogs.com/hjj1871984569/p/10398526.html