解题思路:
利用排序加二分查找的算法,代码中的end是每次算完之后小于key的最大的数的下标,将a中小于b的数的数量算出来之后再进行累加,可以减少c对b中小于c的数的访问时需要从小于c的b中的各个数对应大于a的数的累加。从而缩短计算时间,这个算法的复杂度是O(nlogn)
注意事项:
我语言组织不是很好,所以希望读者代码自己敲一遍,就可以发现其中的奥妙,多调试。
参考代码:
package LanQiao.第九届2018;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.Arrays;
public class Main递增三元组 {
/*
1 2 3
2 3 4
3 4 5
思想:
二分查找
*/
private static StreamTokenizer st =new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
private static int n;
public static void main(String[] args) throws IOException {
double start = System.currentTimeMillis();
st.nextToken();
n=(int)st.nval;
int[] a=new int[n];
int[] b=new int[n];
int[] c=new int[n];
for(int i=0;i<n;i++){
st.nextToken();
a[i]=(int)st.nval;
}
for(int i=0;i<n;i++){
st.nextToken();
b[i]=(int)st.nval;
}
for(int i=0;i<n;i++){
st.nextToken();
c[i]=(int)st.nval;
}
Arrays.sort(a);
Arrays.sort(b);
Arrays.sort(c);
int ltb[]=new int[n];
for(int i=0;i<n;i++){
int key=b[i];
int begin=0,end=n-1;
while(begin<=end){
int mid=(begin+end)/2;
if(a[mid]<key){
begin=mid+1;
}
else{
end=mid-1;
}
}
if(i==0)ltb[i]=end+1;
else ltb[i]=ltb[i-1]+end+1;
}
long ans=0;
for(int i=0;i<n;i++){
int key=c[i];
int begin=0,end=n-1;
while(begin<=end){
int mid=(begin+end)/2;
if(b[mid]<key){
begin=mid+1;
}
else{
end=mid-1;
}
}
if(end!=-1)ans+=ltb[end];
}
System.out.println(ans);
System.out.println(System.currentTimeMillis()-start+"ms");
}
}
0.0分
0 人评分
简单的a+b (C语言代码)浏览:726 |
2003年秋浙江省计算机等级考试二级C 编程题(2) (C语言代码)浏览:629 |
printf基础练习2 (C语言代码)浏览:305 |
用筛法求之N内的素数。 (C语言代码)浏览:1239 |
C语言程序设计教程(第三版)课后习题5.8 (C语言代码)浏览:672 |
C语言程序设计教程(第三版)课后习题6.2 (C语言代码)浏览:703 |
C语言程序设计教程(第三版)课后习题10.3 (C语言代码)浏览:509 |
C二级辅导-求偶数和 (C语言代码)浏览:673 |
C二级辅导-计负均正 (C语言代码)浏览:480 |
字符逆序 (C语言代码)浏览:618 |