2014編程之美初賽2場第3題

題目3 : 集合java

時間限制:12000ms數組

單點時限:6000ms微信

內存限制:256MBapp

描述ide

統計知足下列條件的集合對(A, B)的數量:性能


A,B都是{1, 2, …, N}的子集;測試


A,B沒有公共的元素;大數據


f(A)<= f(B)。f(S)定義爲S中全部元素的按位異或和。例如, f({}) = 0, f({1, 3}) = 2。spa


由於答案可能很大,你只須要求出它除以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;

}

}


更多資訊,請點擊:華萬微信圖文

相關文章
相關標籤/搜索