http://hihocoder.com/contest/offers56/problems
题目1 : 卡片游戏
一开始一直WA,好难找bug,就写了个暴力,随机产生一些输入
package l561;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n=sc.nextInt();
int[]a=new int[n],b=new int[n];
for(int i=0;i<n;i++)a[i]=sc.nextInt();
for(int i=0;i<n;i++)b[i]=sc.nextInt();
Map<Integer, Integer>cnt=new HashMap<Integer, Integer>();
for(int i:a) cnt.put(i,1+(cnt.containsKey(i)?cnt.get(i):0));
int miss=n+1;
for(int i=1;i<=n;i++) {
if(!cnt.containsKey(i)) {
miss=i;
break;
}
}
if(miss==n+1) {
for(int i=0;i<n;i++)
if(a[i]==b[i]) {
System.out.println(n+1);
return;
}
System.out.println(n);
return;
}
int miss2=miss+1;
for(;miss2<=n;miss2++)
if(!cnt.containsKey(miss2)) break;
List<Integer>l=new ArrayList<Integer>();
for(int i=0;i<n;i++) if(b[i]==miss) l.add(a[i]);
int a_minus = -1;
for(int i:l) {
if(i<miss && cnt.get(i)>1) {
System.out.println(miss2);
return;
} else if(i>miss){
if(i>miss2 || cnt.get(i)>1) {
System.out.println(miss2);
return;
}
a_minus=Math.max(a_minus,i);
}
}
System.out.println(a_minus==-1?miss:a_minus);
// if(a_minus==-1) {
// System.out.println(miss);
// return;
// }
//
// if(res<a_minus) System.out.println(res);
// else System.out.println(cnt.get(a_minus)>1?res:a_minus);
}
}
测试代码
package l561;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
public class Test {
public static int m1(int[]a, int[]b, int n) {
Map<Integer, Integer>cnt=new HashMap<Integer, Integer>();
for(int i:a) cnt.put(i,1+(cnt.containsKey(i)?cnt.get(i):0));
int miss=n+1;
for(int i=1;i<=n;i++) {
if(!cnt.containsKey(i)) {
miss=i;
break;
}
}
if(miss==n+1) {
if(miss==n+1) {
for(int i=0;i<n;i++)
if(a[i]==b[i]) {
return (n+1);
}
return (n);
}
}
int miss2=miss+1;
for(;miss2<=n;miss2++)
if(!cnt.containsKey(miss2)) break;
List<Integer>l=new ArrayList<Integer>();
for(int i=0;i<n;i++) if(b[i]==miss) l.add(a[i]);
int a_minus = -1;
for(int i:l) {
if(i<miss && cnt.get(i)>1) {
return (miss2);
} else if(i>miss){
if(i>miss2 || cnt.get(i)>1) {
return (miss2);
}
a_minus=Math.max(a_minus,i);
}
}
return a_minus==-1?miss:a_minus;
}
public static int m2(int[]a, int[]b, int n) {
int res=1;
for(int i=0;i<n;i++) {
Set<Integer>s=new HashSet<Integer>();
for(int j=0;j<n;j++)
if(i==j) s.add(b[j]);
else s.add(a[j]);
int tt=1;
for(;tt<=n;tt++) if(!s.contains(tt)) break;
res=Math.max(res, tt);
}
return res;
}
public static void main(String[] args) {
Random rand = new Random();
int cnt=0;
while(true) {
cnt++;
int n=1+rand.nextInt(100);
int[]a=new int[n],b=new int[n];
for(int i=0;i<n;i++)a[i]=1+rand.nextInt(n+1);
for(int i=0;i<n;i++)b[i]=1+rand.nextInt(n+1);
int t1=m1(a,b,n), t2=m2(a,b,n);
if(t1!=t2)
System.out.println(cnt);
}
}
}
题目2 : 宝藏坐标
跟之前LC一样,就是这里不给用例,完全得自己排bug
题目3 : 物品分类
union find,需要维持不是同一类的set数组,每次union的时候把set数组也union了
为防止TLE,每次合并set数组,选小的遍历,类似于传统union find里面的按秩(规模)归并
直接开set数组会OOM,用HashMap然后删除没用的key,貌似C++没这个问题
package l563;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n=sc.nextInt(), m=sc.nextInt();
int[]a=new int[1+n];
for(int i=1;i<=n;i++) a[i]=i;
Map<Integer, Set<Integer>>not=new HashMap<Integer, Set<Integer>>();
for(int i=1;i<=n;i++) not.put(i, new HashSet<Integer>());
for(int i=0;i<m;i++) {
String s=sc.next();
int p=sc.nextInt(),q=sc.nextInt();
int t1=find(a,p),t2=find(a,q);
if("R".equals(s)) {
int t=sc.nextInt();
if(t==1) {
if(t1==t2) continue; // 这里不写会Run Time error, why?
if(not.get(t1).size()>not.get(t2).size()) {
int tmp=t1;
t1=t2;
t2=tmp;
}
a[t1]=t2;
merge(not.get(t1), not.get(t2), a); // 合并root的时候也合并not集合
not.remove(t1);
} else {
not.get(t1).add(t2);
not.get(t2).add(t1);
}
} else {
if(t1==t2) System.out.println(1);
else System.out.println(((not.containsKey(t1)&¬.get(t1).contains(t2))||
(not.containsKey(t2)&¬.get(t2).contains(t1)))?2:3);
}
}
}
private static void merge(Set<Integer> s1, Set<Integer> s2, int[] a) {
for(int t:s1) {
int tt = find(a,t);
s2.add(tt);
}
}
private static int find(int[] a, int p) {
while(p!=a[p]) p=a[p];
return p;
}
}
为了找bug,也是醉了,写了很多测试OJ的代码
while(not[t1]==null||not[t2]==null);
for(int t:s1) {
try {
} catch (Exception e) {
System.out.println(123456);
}
}