#37799: 卡在30%


zhoudaniel02@gmail.com (周孝倫)

學校 : 銘傳大學
編號 : 235507
來源 : [223.136.106.199]
最後登入時間 :
2024-05-17 11:23:31
k734. 4. 開啟寶盒 -- 2023年6月APCS | From: [223.137.53.228] | 發表日期 : 2023-10-08 18:01

我弄得東西是將全部的寶相都加進linkedlist,寶箱的實例會存放兩個矩陣:需要的鑰匙跟彈出的鑰匙,將所有擁有的鑰匙都加進HashMap裡

重複遍歷寶箱值到linkedlist沒東西:

 變歷寶箱需要的鑰匙,如果遇到沒有匹配的就continue到下個寶箱,都能匹配就將寶箱移出,把寶箱裡的鑰匙都加進HashMap中

因為k太小了,我算的時間複雜度是O(n^2)

package a;

import java.util.*;

import java.util.Map.Entry;

public class k734 {

public static void main(String []args) {

Scanner sc=new Scanner(System.in);

String[]s=sc.nextLine().split(" ");

Map<Integer,Boolean>mykey=new LinkedHashMap<>();

int n=Integer.parseInt(s[0]);

Map<box,Integer>allbox=new HashMap<>();

int k=Integer.parseInt(s[2]);

int[][]nk=new int[n][k];

int[][]nk2=new int[n][k];

s=sc.nextLine().split(" ");

for(int i=1;i<s.length;i++)

mykey.put(Integer.parseInt(s[i]), true);

for(int i=0;i<n;i++) {

s=sc.nextLine().split(" ");

for(int j=0;j<k;j++)

nk[i][j]=Integer.parseInt(s[j]);

}

for(int i=0;i<n;i++) {

s=sc.nextLine().split(" ");

for(int j=0;j<k;j++)

nk2[i][j]=Integer.parseInt(s[j]);

}

for(int i=0;i<n;i++)

allbox.put(new box(nk[i],nk2[i]),0);//n<17500,O(n)

int openedbox=0;

boolean keep=true;

Queue<box>removeit=new LinkedList<>();

while(keep) {

keep=false;

while(!removeit.isEmpty())

allbox.remove(removeit.poll());

findingbox:for(Entry<box, Integer> e : allbox.entrySet()) {

for(int i:e.getKey().keyin)

if(mykey.get(i)==null)

continue findingbox;

e.getKey().lock=false;

removeit.add(e.getKey());

openedbox++;

for(int i:e.getKey().keyout)

mykey.put(i, true);

keep=true;

}

}

System.out.println(openedbox);

}

}

class box {

boolean lock=true;

int[]keyin;

int[]keyout;

public box(int[]in,int[]out) {

this.keyin=in;

this.keyout=out;

}

}

 
#38551: Re: 卡在30%


jenniferhesterchen@gmail.com (Jennifer Chen)

學校 : 不指定學校
編號 : 253780
來源 : [61.216.20.43]
最後登入時間 :
2024-03-18 12:29:38
k734. 4. 開啟寶盒 -- 2023年6月APCS | From: [122.146.84.120] | 發表日期 : 2023-12-06 10:51

我弄得東西是將全部的寶相都加進linkedlist,寶箱的實例會存放兩個矩陣:需要的鑰匙跟彈出的鑰匙,將所有擁有的鑰匙都加進HashMap裡

重複遍歷寶箱值到linkedlist沒東西:

 變歷寶箱需要的鑰匙,如果遇到沒有匹配的就continue到下個寶箱,都能匹配就將寶箱移出,把寶箱裡的鑰匙都加進HashMap中

因為k太小了,我算的時間複雜度是O(n^2)

package a;

import java.util.*;

import java.util.Map.Entry;

public class k734 {

public static void main(String []args) {

Scanner sc=new Scanner(System.in);

String[]s=sc.nextLine().split(" ");

Mapmykey=new LinkedHashMap<>();

int n=Integer.parseInt(s[0]);

Mapallbox=new HashMap<>();

int k=Integer.parseInt(s[2]);

int[][]nk=new int[n][k];

int[][]nk2=new int[n][k];

s=sc.nextLine().split(" ");

for(int i=1;i<s.length;i++)

mykey.put(Integer.parseInt(s[i]), true);

for(int i=0;i<n;i++) {

s=sc.nextLine().split(" ");

for(int j=0;j<k;j++)

nk[i][j]=Integer.parseInt(s[j]);

}

for(int i=0;i<n;i++) {

s=sc.nextLine().split(" ");

for(int j=0;j<k;j++)

nk2[i][j]=Integer.parseInt(s[j]);

}

for(int i=0;i<n;i++)

allbox.put(new box(nk[i],nk2[i]),0);//n<17500,O(n)

int openedbox=0;

boolean keep=true;

Queueremoveit=new LinkedList<>();

while(keep) {

keep=false;

while(!removeit.isEmpty())

allbox.remove(removeit.poll());

findingbox:for(Entry e : allbox.entrySet()) {

for(int i:e.getKey().keyin)

if(mykey.get(i)==null)

continue findingbox;

e.getKey().lock=false;

removeit.add(e.getKey());

openedbox++;

for(int i:e.getKey().keyout)

mykey.put(i, true);

keep=true;

}

}

System.out.println(openedbox);

}

}

class box {

boolean lock=true;

int[]keyin;

int[]keyout;

public box(int[]in,int[]out) {

this.keyin=in;

this.keyout=out;

}

}

請問你解決了嗎?我也卡在30%...><

 
#38663: Re: 卡在30%


liaoweichen1024@gmail.com (M_SQRT)

學校 : 新北市立新莊高級中學
編號 : 195452
來源 : [210.71.71.103]
最後登入時間 :
2024-05-17 09:42:48
k734. 4. 開啟寶盒 -- 2023年6月APCS | From: [210.71.71.103] | 發表日期 : 2023-12-14 12:47

我弄得東西是將全部的寶相都加進linkedlist,寶箱的實例會存放兩個矩陣:需要的鑰匙跟彈出的鑰匙,將所有擁有的鑰匙都加進HashMap裡

重複遍歷寶箱值到linkedlist沒東西:

 變歷寶箱需要的鑰匙,如果遇到沒有匹配的就continue到下個寶箱,都能匹配就將寶箱移出,把寶箱裡的鑰匙都加進HashMap中

因為k太小了,我算的時間複雜度是O(n^2)

package a;

import java.util.*;

import java.util.Map.Entry;

public class k734 {

public static void main(String []args) {

Scanner sc=new Scanner(System.in);

String[]s=sc.nextLine().split(" ");

Mapmykey=new LinkedHashMap<>();

int n=Integer.parseInt(s[0]);

Mapallbox=new HashMap<>();

int k=Integer.parseInt(s[2]);

int[][]nk=new int[n][k];

int[][]nk2=new int[n][k];

s=sc.nextLine().split(" ");

for(int i=1;i<s.length;i++)

mykey.put(Integer.parseInt(s[i]), true);

for(int i=0;i<n;i++) {

s=sc.nextLine().split(" ");

for(int j=0;j<k;j++)

nk[i][j]=Integer.parseInt(s[j]);

}

for(int i=0;i<n;i++) {

s=sc.nextLine().split(" ");

for(int j=0;j<k;j++)

nk2[i][j]=Integer.parseInt(s[j]);

}

for(int i=0;i<n;i++)

allbox.put(new box(nk[i],nk2[i]),0);//n<17500,O(n)

int openedbox=0;

boolean keep=true;

Queueremoveit=new LinkedList<>();

while(keep) {

keep=false;

while(!removeit.isEmpty())

allbox.remove(removeit.poll());

findingbox:for(Entry e : allbox.entrySet()) {

for(int i:e.getKey().keyin)

if(mykey.get(i)==null)

continue findingbox;

e.getKey().lock=false;

removeit.add(e.getKey());

openedbox++;

for(int i:e.getKey().keyout)

mykey.put(i, true);

keep=true;

}

}

System.out.println(openedbox);

}

}

class box {

boolean lock=true;

int[]keyin;

int[]keyout;

public box(int[]in,int[]out) {

this.keyin=in;

this.keyout=out;

}

}

 

Map不要亂用
mykey的部分,mykey.key是連續的[0, 100000),請使用boolean陣列,或是BitSet會更好。

 Mapboolean[]BitSet
查找logN11
插入logN11
記憶體超大M bytesM/8 bytes
常數超級大幾乎為0比boolean[]略大


還有我改到一半,才發現你的findingBox是暴搜,這題用暴搜「應該」是會爛掉的啦,這邊的做法有點類似拓撲排序,可以O(1)找到可以開的寶盒。

 

import java.util.*;

import java.util.Map.Entry;

public class Main {

 public static void main(String[] args) {

  Scanner sc = new Scanner(System.in);

  BitSet mykey = new BitSet(100000);

  int n = sc.nextInt();

  sc.nextInt();

  Map<box, Integer> allbox = new HashMap<>();

  int k = sc.nextInt();

  int[][] nk = new int[n][k];

  int[][] nk2 = new int[n][k];

  int len = sc.nextInt();

  for (int i=0; i<len; i++)

   mykey.set(sc.nextInt());

  for (int i = 0; i < n; i++) {

   for (int j = 0; j < k; j++)

    nk[i][j] = sc.nextInt();

  }

  for (int i = 0; i < n; i++) {

   for (int j = 0; j < k; j++)

    nk2[i][j] = sc.nextInt();

  }

  for (int i = 0; i < n; i++)

   allbox.put(new box(nk[i], nk2[i]), 0);// n<17500,O(n)

  int openedbox = 0;

  boolean keep = true;

  Queue<box> removeit = new LinkedList<>();

  while (keep) {

   keep = false;

   while (!removeit.isEmpty())

    allbox.remove(removeit.poll());

   findingbox:for (Entry<box, Integer> e : allbox.entrySet()) {

    for (int i : e.getKey().keyin)

     if (!mykey.get(i))

      continue findingbox;

    e.getKey().lock = false;

    removeit.add(e.getKey());

    openedbox++;

    for (int i : e.getKey().keyout)

     mykey.set(i);

    keep = true;

   }

  }

  System.out.println(openedbox);

 }

}

class box {

 boolean lock = true;

 int[] keyin;

 int[] keyout;

 public box(int[] in, int[] out) {

  this.keyin = in;

  this.keyout = out;

 }

}

 

 
ZeroJudge Forum