题目3 : 集合
时间限制:12000ms
单点时限:6000ms
内存限制:256MB
描述
统计满足下列条件的集合对(A, B)的数量:
A,B都是{1, 2, …, N}的子集;
A,B没有公共的元素;
f(A)<= f(B)。f(S)定义为S中所有元素的按位异或和。例如, f({}) = 0, f({1, 3}) = 2。
因为答案可能很大,你只需要求出它除以M的余数。
输入
第一行一个整数T (1 ≤ T ≤ 10),表示数据组数。
接下来是T组输入数据,测试数据之间没有空行。
每组数据格式如下:
仅一行,2个整数N和M (1 ≤ M ≤ 108)。
输出
对每组数据,先输出“Case x: ”,然后接一个整数,表示所求的结果。
数据范围
小数据:1 ≤ N ≤ 20
大数据:1 ≤ N < 212
样例输入
1
3 100000000
样例输出
Case 1: 18
解题思路:
用了暴力求解,性能真的令人担忧,N=10及以下可以畅快运行,以上的话就不可以了,解题仅供参考。不建议这么做。
求出N个数所有的子集。求子集的方法是通过,遍历从0-(2^n-1),变成二进制的形式,0为该位置的数不出现,1为该位置的数出现。
求出每个子集对应的异或和。
两次循环遍历,寻找符合条件的数组,用Count计算。
最后取模输出答案。
java代码:
package ruming.wei;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;
public class chusai2_q3 {
public static void main(String[] args) {
chusai2_q3 app=new chusai2_q3();
Scanner in = new Scanner(System.in);
String input=in.nextLine();
int T=Integer.valueOf(input);
for(int i=0;i<T;i++){
input=in.nextLine();
int N,M;
N=Integer.parseInt(input.split(" ")[0]);
M=Integer.parseInt(input.split(" ")[1]);
HashMap<HashSet<String>, Integer> all=app.createAll(N);
Iterator iterator1=all.entrySet().iterator();
int count=0;
while(iterator1.hasNext()){
Map.Entry entry1=(Map.Entry)iterator1.next();
Iterator iterator2=all.entrySet().iterator();
HashSet<String> setA=(HashSet<String>) entry1.getKey();
while(iterator2.hasNext()){
Map.Entry entry2=(Map.Entry)iterator2.next();
HashSet<String> setB=(HashSet<String>) entry2.getKey();
boolean flag=true;
for(String aString:setA){
for(String bString:setB)
{
if(!aString.equals("null")&&aString.equals(bString))
{
flag=false;
break;
}
}
}
int Axor=(Integer)entry1.getValue();
int Bxor=(Integer)entry2.getValue();
if(flag&&Axor<=Bxor)
{
count++;
System.out.println("A:"+setA+"-->"+Axor+" "+"B:"+setB+"-->"+Bxor);
}
}
//System.out.println(entry1.getKey()+"-->"+entry1.getValue());
}
System.out.println("Case "+(i+1)+": "+count%M);
}
}
private HashMap<HashSet<String>, Integer> createAll(int N){
int count=2<<(N-1);
HashMap<HashSet<String>, Integer> all= new HashMap<HashSet<String>, Integer>();
for(int i=0;i<count;i++){
String str=String.valueOf(Integer.toBinaryString(i));
while(str.length()<N)
str ="0"+str;//以‘0’向前填充字符串为N个字符
if(i==0)
{
HashSet<String> set=new HashSet<String>();
set.add("null");
all.put(set, 0);
}
else {
String change="";
HashSet<String> set=new HashSet<String>();
for(int j=0;j<str.length();j++){
char cc=str.charAt(j);
if(cc=='1')
{
change +=String.valueOf(j+1)+" ";
set.add(String.valueOf(String.valueOf(j+1)));
}
}
all.put(set, f(change));
}
}
return all;
}
private int f(String change) {
String[] subs=change.split(" ");
int xor=Integer.parseInt(subs[0]);
for(int i=1;i<subs.length;i++){
xor ^=Integer.parseInt(subs[i]);
}
return xor;
}
}
更多资讯,请点击:华万微信图文