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相等.
代码:由于使用的是链表,代码有点乱,凑活着看
#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