Day2 T3 删除

题目

  Alice上化学课时又分心了,他首先画了一个3行N列的表格,然后把数字1到N填入表格的第一行,保证每个数只出现一次,另外两行他也填入数字1到N,但不限制每个数字的出现次数。
  Alice现在想删除若干列使得每一行排完序后完全一样,编程计算最少需要删除多少列。

输入

第一行包含一个整数N,表示表格的列数。
接下来三行每行包含N个整数,每个数在1到N之间,而且第一行的数互不相同。

输出

输出最少需要删除的列数。

样例

输入 输出
7
5 4 3 2 1 6 7
5 5 1 1 3 4 7
3 7 1 4 5 6 2
4
9
1 3 5 9 8 6 2 4 7
2 1 5 6 4 9 3 4 7
3 5 1 9 8 6 2 8 7
2

样例解释

例1中Alice需要删除第2、4、6、7这四列,然后每行排完序都是1、3、5。

数据范围

40%的数据N (leqslant) 100
70%的数据N (leqslant) 10000
100%的数据N (leqslant) 100000

题解

  まび这么简单一道题我考场上竟然没有做出来。
  开两个桶记录第二行和第三行每一个数出现的次数,然后扫一遍第一行,如果某一个数第一行有而第二、三行没有,那么就要删除这一列。而在这个过程中又会删除掉第二、三行的一些数,可能会导致又有某一个数第一行有而第二、三行没有,所以又要重复这一操作,直到第一行的每一个数在第二、三行都有,这个时候三行的数就都一样了。

#include<bits/stdc++.h>
using namespace std;
int n,ans=0;
int a[100010],b[100010],c[100010];
int tb[100010]={0},tc[100010]={0};
bool book[100010]={false};

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=n;i++){
        scanf("%d",&b[i]);
        tb[b[i]]++;
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&c[i]);
        tc[c[i]]++;
    }
    for(;;){
        bool flag=false;
        for(int i=1;i<=n;i++){
            if(book[i]) continue;
            if(!tb[a[i]] || !tc[a[i]]){
                book[i]=true;
                ans++;
                tb[b[i]]--;
                tc[c[i]]--;
                flag=true;
            }
        }
        if(!flag) break;
    }
    printf("%d",ans);
	return 0;
}
原文地址:https://www.cnblogs.com/znk161223/p/11453143.html