未分类 - Gemini Boy - ACM之路~

20130926 - 初级魔法练习

叉姐の魔法训练

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=32389#overview

 

A: Set Operatoin (POJ2443)

题意是:有n个集合(n<=1000), 每个集合有m个数ai(m<=10000, 1=<ai<=10000),同一个集合中可能有相同的数.有q个查询(q<=200000),对于每个查询a,b,问是否存在一个集合同时包含a和b。

做法就是压位加速,将每一个集合看成是一行,也成了一个1000*10000的0、1矩阵,对于每个数来书,它所在的列的0、1分布情况也就是它所在集合的情况。但问题是现在一共有1000行,2^1000肯定不行,但考虑到一个int可以存32位(2^32),1000<32*32,所以可以开32个整数,每个整数的二进制的每一位代表每一行,这样就可以在q*32的可接受的时间复杂度内查询出结果。将扫描1000变为扫描32,利用整数的位操作减少为1/32。

代码君:

package NO20130926;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class POJ2443 {

	public void run() {
		InputReader cin = new InputReader(System.in);
		PrintWriter cout = new PrintWriter(new OutputStreamWriter(System.out));

		int[][] map = new int[10010][100];
		int n = cin.nextInt();
		for (int i = 0; i < n; i++) {
			int c = cin.nextInt();
			for (int j = 0; j < c; j++) {
				int x = cin.nextInt();
				map[x][i / 30] |= 1 << (i % 30);
			}
		}
		int q = cin.nextInt();
		for (int cas = 0; cas < q; cas++) {
			int a = cin.nextInt();
			int b = cin.nextInt();
			boolean ok = false;
			for (int i = 0; i < 35; i++) {
				if ((map[a][i] & map[b][i]) > 0) {
					cout.println("Yes");
					ok = true;
					break;
				}
			}
			if (ok == false)
				cout.println("No");
		}

		cout.flush();
	}

	public static void main(String args[]) {
		new POJ2443().run();
	}

	class InputReader {

		public BufferedReader reader;
		public StringTokenizer tokenizer;

		public InputReader(InputStream stream) {
			reader = new BufferedReader(new InputStreamReader(stream));
			tokenizer = null;
		}

		public InputReader() throws FileNotFoundException {
			reader = new BufferedReader(new FileReader("d:/input.txt"));
			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());
		}

	}
}

当然也可以用C++ STL的bitset或java的bitset直接来做。

乱七八糟的动态规划

HDU 3664: Permutation Counting




Host by is-Programmer.com | Power by Chito 1.3.3 beta | © 2007 LinuxGem | Design by Matthew "Agent Spork" McGee