• 【HIHOCODER 1513】 小Hi的烦恼 (BitSet)


    描述


    小Hi从小的一大兴趣爱好就是学习,但是他发现尽管他认真学习,依旧有学神考的比他好。
    小Hi在高中期间参加了市里的期末考试,一共五门:语文、数学、英语、物理、化学。
    成绩出来之后,小Hi发现有些同学,所有科目都考的比他好,他很烦恼。所以他想知道所有科目都比自己名次靠前的同学的人数。
    为了方便,可以认为不存在两个人某一门名次是相同的。
    其他同学们也想知道有多少人全面碾压了他们,所以你需要对所有人输出答案。
    解题方法提示

    输入


    第一行,一个正整数N(N <= 30000),表示人数。
    接下来N行,每行五个整数,分别表示五门课依次的排名。

    输出


    输出共N行,每行一个整数,表示答案。

    样例输入

    4
    1 1 2 2 1
    2 3 3 3 2
    3 2 1 1 3
    4 4 4 4 4
    

    样例输出

    0
    1
    0
    3
    

    题解


    BitSet就是一个大二进制串,同时实现了二进制数的各种位运算,我们利用任意位上的值为0或1来标志集合中是否存在这个数,可以有效的节约空间,同时也方便了各种集合运算。
    BitSet内部实现以每32位转化为32位整型,然后32位的运算变为一次位运算,这样可以把整体(O(n))的集合运算转化为(O(n/32))
    链接:BitSet常用方法
    排名肯定是连续的,对于每一科排名,从前到后累计一下之前是那些人,最后在对第i个人每一科排名之前的人集合求一个交集。

    Java版

    import java.io.*;
    import java.util.*;
    
    public class Main {
    	static final int N=30005;
    	static final int inf=0x3f3f3f3f;
        static BitSet vis[][]=new BitSet[N][5];
        static BitSet a[]=new BitSet[N];
        static int id[][]=new int[N][5];
        static int x[][]=new int[N][5];
    	public static void main(String[] args) {         
            InputStream sys=System.in;
            InputReader in=new InputReader(sys);
            PrintWriter out=new PrintWriter(System.out);
            int n=in.nextInt();
            for(int i=0;i<n;i++) {
            	for(int j=0;j<5;j++) {
            		x[i][j]=in.nextInt();
                    id[x[i][j]][j]=i;
                    vis[i][j]=new BitSet();
            	}
            	a[i]=new BitSet();
            	a[i].set(i,true);
            }
            for(int j=0;j<5;j++) {
            	vis[n][j]=new BitSet();
            }
            for(int i=1;i<=n;i++) {
            	for(int j=0;j<5;j++) {
            		vis[i][j]=(BitSet) vis[i-1][j].clone();
            		if(i<n) vis[i][j].set(id[i][j],true);
            	}
            }
            BitSet ans=new BitSet();
            for(int i=0;i<n;i++) {
            	ans=(BitSet) vis[x[i][0]][0].clone();
            	for(int j=1;j<5;j++) {
            		ans.and(vis[x[i][j]][j]);
            	}
                ans.andNot(a[i]);
            	out.println(ans.cardinality());
            }
            out.flush();
        }
    	static class InputReader {
    		public BufferedReader reader;
    		public StringTokenizer tokenizer;
            
    		public InputReader(InputStream stream) {
    			reader = new BufferedReader(new InputStreamReader(stream), 32768);
    			tokenizer = null;
    		}
    
    		public String next() {
    			while (tokenizer == null || !tokenizer.hasMoreTokens()) {
    				try {
    					tokenizer = new StringTokenizer(reader.readLine());
    				} catch (IOException e) {
    					throw new RuntimeException(e);
    				}
    			}
    			return tokenizer.nextToken();
    		}
    
    		public int nextInt() {
    			return Integer.parseInt(next());
    		}
    		
    		public long nextLong() {
    			return Long.parseLong(next());
    		}
    		
    		public double nextDouble() {
    			return Double.parseDouble(next());
    		}
    	}
    }
    

    C++版

    #include <bitset>
    #include <queue>
    #include <cmath>
    #include <cstdio>
    #include <complex>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    #define inf 1000000000
    #define PI acos(-1)
    #define REP(i,x,n) for(int i=x;i<=n;i++)
    #define DEP(i,n,x) for(int i=n;i>=x;i--)
    #define mem(a,x) memset(a,x,sizeof(a))
    using namespace std;
    ll read(){
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    void Out(ll a){
        if(a<0) putchar('-'),a=-a;
        if(a>=10) Out(a/10);
        putchar(a%10+'0');
    }
    const int N=30005;
    int x[N][5],id[N][5];
    bitset<N> vis[N][5],a[N];
    bitset<N> ans;
    int main(){
        int n=read();
        for(int i=0;i<n;i++) {
            for(int j=0;j<5;j++) {
                x[i][j]=read();
                id[x[i][j]][j]=i;
            }
            a[i].set();
            a[i][i]=false;
        }
        for(int i=1;i<=n;i++) {
            for(int j=0;j<5;j++) {
                vis[i][j]=vis[i-1][j];
                if(i<n) vis[i][j].set(id[i][j],true);
            }
        }
        for(int i=0;i<n;i++) {
            ans=vis[x[i][0]][0];
            for(int j=1;j<5;j++) {
                ans&=vis[x[i][j]][j];
            }
            ans&=a[i];
            Out(ans.count());
            puts("");
        }
        return 0;
    }
    
  • 相关阅读:
    【.Net Micro Framework PortingKit 07】NVIC中断处理
    【.Net Micro Framework PortingKit 02】STM3210E平台构建
    【.Net Micro Framework PortingKit 06】设置芯片时钟
    【.Net Micro Framework PortingKit 03】调试初步:点亮LED灯
    【.Net Micro Framework PortingKit 01】移植初步:环境搭建
    开源System.Windows.Forms库,让.Net Micro Framework界面开发和上位机一样简单
    RVDS和MDK嵌入式开发工具调试脚本编写
    JQuery移除事件 简单
    Visual C++ 2008入门经典 第十六章 创建文档和改进视图 简单
    Visual C++ 2008入门经典 第十五章 在窗口中绘图 简单
  • 原文地址:https://www.cnblogs.com/zsyacm666666/p/7371904.html
Copyright © 2020-2023  润新知