题解 P7935 [COCI2007-2008#5] AVOGADRO
思路:
将第一、二、三行的序列分别称为
显然,当序列
题目中保证序列
然而,必须整列删除,因此删除时还会删掉序列
我选择用队列记录要删除哪些数字,每次弹出队首,并删除队首数字在序列
当队列空时,说明
代码:
//代码中i均指该数组中的下标
#include<bits/stdc++.h>
using namespace std;
struct node{
int a,b,c;
}s[100003];//在s中,下标代表列
queue<int> del;
int t[100003];//记录数字i在哪一列
int cntb[100003],cntc[100003];//记录b,c中有几个数字i
int ans;
int n;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&s[i].a);
t[s[i].a]=i;
}
for(int i=1;i<=n;i++){
scanf("%d",&s[i].b);
cntb[s[i].b]++;//在计数器中增加数字s[i].b的数量
}
for(int i=1;i<=n;i++){
scanf("%d",&s[i].c);
cntc[s[i].c]++;
}
for(int i=1;i<=n;i++)
if(!cntb[i]||!cntc[i])del.push(i);//如果缺少数字i,将其加入队列
while(!del.empty()){
int x=del.front();//我们要删掉数字x
del.pop();
if(t[x]==0)continue;//已经删过数字x了,跳过。
ans++;
cntb[s[t[x]].b]--;
cntc[s[t[x]].c]--;
if(cntb[s[t[x]].b]==0)del.push(s[t[x]].b);
if(cntc[s[t[x]].c]==0)del.push(s[t[x]].c);
t[x]=0;//标记数字x已经被删了
}
printf("%d",ans);
return 0;
}