Codeforces Round #699 Problem C Fence Painting 贪心

https://codeforc.es/contest/1481/problem/C

题意:n块栅栏,告诉你原先的颜色和期望得到的颜色,并告诉你每位油漆工必须刷上的一个颜色,问你安排每位油漆工刷哪块栅栏能使栅栏变成期望的颜色.

思路核心:浪费,怼着一块板(最后一个油漆工要刷的板)拼命刷那些不需要的颜色(这样相当于遣散了一些油漆工)

具体:

原颜色是org[i],目标颜色是tar[],刷漆工要刷的颜色must[]

看最后一个刷漆的颜色must[m]是否在tar中出现,无则NO,有则记录使tar[last]=must[m]的last

遍历tar,将tar与org不同的记录下来(用数组needlist(模型是一行1~n的数组,每个元素向上伸出这个颜色要改的位置),
然后遍历must,若某tar的颜色有需求要改(needlist每个元素都有一个index,用来指向目前这个颜色最新需求要修改的pos,即必有tar[pos]!=org[pos]),若不需要修改,直接刷到last那里去.最后将must[m]刷到last去
最后看org是否和tar相等.

 

代码:由于使用的是链表,代码有点乱,凑活着看

Codeforces Round #699 Problem C Fence Painting 贪心
#include<iostream>
#include<string>
#include<algorithm>
#include<string.h>
#include<cmath>
#define rep(i,a,b) for(ll i=a;i<=b;++i)
#define per(i,a,b) for(ll i=a;i>=b;--i)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn=1e5+10;

int org[maxn],tar[maxn];
int must[maxn];
int ans[maxn];
typedef struct Need{
    int pos;
    Need* next;
};
typedef struct{
    Need* index;
    Need* firstneed;
}Needlist[maxn];

Needlist needlist;

int n,m;
void Init(){
    rep(i,1,maxn-1){
        needlist[i].firstneed=new Need();
    }
}
void Freelist(){
    int i=1;
    for(;i<=maxn-1;++i){
        needlist[i].firstneed->pos=0;
        Need *now=needlist[i].firstneed->next,*front;
        while(now){
            front=now;    now=now->next;    delete front;
        }
        /*if(i==8){
            int a=0;
        }*/
        needlist[i].firstneed->next=needlist[i].index=NULL;
    }
    
}

bool Check(){
    rep(i,1,n) if(org[i]!=tar[i]) return 0;
    return 1;
}
int last=0;
void Changelast(){
    Need *now=needlist[must[m]].firstneed,*front;
    while(now){
        front=now;    now=now->next;
    }
    last=front->pos;
}

int main()
{
    Init();
    int t ;
    cin>>t;
    while(t--){
         cin>>n>>m;

        rep(i,1,n) cin>>org[i];
        rep(i,1,n) cin>>tar[i];
        rep(i,1,m) cin>>must[i];
            
        rep(i,1,n){
            if(tar[i]!=org[i]) {
                    Need * front=needlist[tar[i]].firstneed,*now;
                    if(front->pos==0){
                        needlist[tar[i]].firstneed->pos=i;    needlist[tar[i]].firstneed->next=NULL;
                        needlist[tar[i]].index=needlist[tar[i]].firstneed;
                    } 
                    else {
                        now=new Need();
                        now->pos=i;    now->next=front->next;
                        front->next=now;    
                    }
                }    
            else if(tar[i]==must[m]) last=i;
        }
        
        if(needlist[must[m]].firstneed->pos)    Changelast();
        if(!last) cout<<"NO"<<endl;
        else{    
            rep(i,1,m-1){
                if(!needlist[must[i]].index) {
                    ans[i]=last;
                    org[last]=must[i];
                }
                else{
                    ans[i]=needlist[must[i]].index->pos;
                    org[needlist[must[i]].index->pos]=must[i];
                    needlist[must[i]].index=needlist[must[i]].index->next;    
                }
            }
            ans[m]=last;    org[last]=must[m];
            
            if(Check()){
                cout<<"YES"<<endl;
                rep(i,1,m) cout<<ans[i]<<' ';
                cout<<endl;
            }
            else cout<<"NO"<<endl;
        }
                
        Freelist();
        last=0;
    }
    return 0;
}
/*
1
5 4
1 2 3 4 5
1 2 3 4 6
1 2 3 4
*/

/*
3
10 5
7 3 2 1 7 9 4 2 7 9
9 9 2 1 4 9 4 2 3 9
9 9 7 4 3
5 2
1 2 2 1 1
1 2 2 1 1
3 3
6 4
3 4 2 4 1 2
2 3 1 3 1 1
2 2 3 4
*/

/*
3
5 5
1 2 3 4 5
1 2 3 5 5
6 6 5 5 5
5 5
1 2 3 4 5
1 2 3 5 5
5 5 5 6 5
5 6
1 2 3 4 5
1 2 3 4 5
1 2 6 3 5 4
*/

/*
2
5 3
1 2 4 4 5
1 2 3 3 3
3 3 3
5 5
1 2 3 4 5
1 2 3 5 5
7 8 9 6 5

*/
View Code

 

上一篇:linux DRM GPU scheduler 笔记


下一篇:Redis基本命令及Java API操作