int main(){

   while(模拟赛) 降智++;

    return inf;

}

题目

T1

刚看到题时还以为不可做,重新看了几遍之后才发现以前好像做过……

做法很显然吧……

由于第一行存在 $1-n$ 的数各一个,我们可以先把列 按照第一行的数从大到小排序,这样第 $i$ 列第 $1$ 行的数就是 $i$ 了,方便后续操作。

容易发现,如果第 $2$ 或 第 $3$ 行不存在某个数,那第一行的这个数肯定匹配不上 $2$、$3$ 行相同的数,把这个数在第一行所在的那一列删掉。

然后删掉一列之后,第 $2$、$3$ 行就各少了一个数,那第 $2$ 或 第 $3$ 行就有可能又出现一个不存在的数。重复上述删除过程即可。

可以把要删除的列的编号扔进一个队列,挨个取出后操作。时间复杂度是列数级别,即 $O(n)$。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 inline int read(){
 4     int x=0; bool f=1; char c=getchar();
 5     for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
 6     for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+(c^'0');
 7     if(f) return x;
 8     return 0-x;
 9 }
10 int n;
11 struct num{
12     int v[4];
13     bool operator <(const num &x)const{
14         return v[0]<x.v[0];
15     }
16 }a[100002];
17 int cnt[100002],_cnt[100002],ans;
18 bool del[100002];
19 int main(){
20     freopen("avogadro.in","r",stdin);
21     freopen("avogadro.out","w",stdout);
22     n=read();
23     int i,j;
24     for(i=0;i^3;++i)
25         for(j=1;j<=n;++j)
26             a[j].v[i]=read();
27     sort(a+1,a+n+1);
28     for(i=1;i<=n;++i) ++cnt[a[i].v[1]], ++_cnt[a[i].v[2]];
29     queue<int>Q;
30     for(i=1;i<=n;++i) if(!cnt[i] || !_cnt[i]) Q.push(i), del[i]=1;
31     int u;
32     while(!Q.empty()){
33         u=Q.front(), Q.pop();
34         ++ans;
35         //printf("%d %d %d %d\n",u,a[u].v[1],a[u].v[2],ans);
36         if(--cnt[a[u].v[1]]==0 && !del[a[u].v[1]]) del[a[u].v[1]]=1, Q.push(a[u].v[1]);
37         if(--_cnt[a[u].v[2]]==0 && !del[a[u].v[2]]) del[a[u].v[2]]=1, Q.push(a[u].v[2]);
38     }
39     printf("%d\n",ans);
40     return 0;
41 }
View Code

相关文章:

  • 2022-02-17
  • 2022-12-23
  • 2021-04-03
  • 2021-11-22
  • 2022-12-23
  • 2021-11-04
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-11-10
  • 2022-01-07
  • 2021-11-20
  • 2021-10-05
相关资源
相似解决方案