星际争霸
问题描述
在星际争霸的世界中,每个种族都有自己独特的技术和战略。Protoss种族的指挥官们已经研发出了一种新的战略来对抗他们的敌人。
他们有一种叫做 Psionic Matrix 的设备,可以储存并分析战斗数据。这个设备可以记录每个单位的战斗力,这个战斗力被表示为一个正整数。随着战斗的进行,这些战斗力值会被储存在一个数组 aa 中。
现在,指挥官们想要对这些战斗力值进行排序。他们发现,每次在排序过程中更改两个数的位置,都会产生一种 Psionic Disturbance (灵能干扰)。为了尽量减少这种干扰,他们希望按照逆序对的数量进行排序。如果两个数的逆序对数量相同,他们会根据数值的大小进行排序。
请你帮助他们完成这个任务。
输入格式
第一行输入一个正整数 nn,表示数组的长度。
接下来 nn 行每行输入一个正整数 aiai,表示数组 aa 中的第 ii 个元素。
输出格式
输出共 nn 行,每行输出一个整数,表示排序后的数组 aa。
样例输入
5
12
31
45
123
452
样例输出
12
45
123
31
452
说明
1212 的逆序对数为 00,3131 的逆序对数为 11,4545 的逆序对数为 00,123123 的逆序对数为 00,452452 的逆序对数为 22。
故最终排序结果为 12[0]12[0],45[0]45[0],123[0]123[0],31[1]31[1],452[2]452[2],[][] 中的数表示逆序对数。
数据范围
对于 100100% 的数据,1≤n≤10001≤n≤1000,1≤ai≤1010001≤ai≤101000,aiai 可能包含前导 00,输出时请保留前导零。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class Main {
static Map<Integer, Integer> map=new HashMap<Integer, Integer>();
static int N=10000,idx;//res=0;
//static Integer a[]=new Integer[N];
static String stringa[]=new String[N];
static Node node[]=new Node[N];
// static boolean f[]=new boolean[N];
public static void main(String[] args) throws IOException {
//System.out.println(100);
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int n=Integer.parseInt(br.readLine());
//String g[]=br.readLine().split(" ");
for (int i = 0; i < n; i++) {
String t=br.readLine();
node[i]=new Node(cal(t),t);
}
Arrays.sort(node,0,n,(Node a,Node b)->{
if(a.revnum==b.revnum){//注意:这里一定不能用字符串比较 e.g 10,2
BigInteger bigInteger1 =new BigInteger(a.num);
BigInteger bigInteger2 =new BigInteger(b.num);
return bigInteger1.compareTo(bigInteger2);
}else{
return Long.compare(a.revnum,b.revnum);
}
});
for (int i = 0; i < n; i++) {
System.out.println(node[i].num);
}
}
static long cal(String n){
long res=0;
//BigInteger bigInteger=new BigInteger(n);
char c[]=n.toCharArray();
int cnt[]=new int[10];//核心是只有数值0-9
for (int i = 0; i < c.length; i++) {
int f=c[i]-'0';
for (int j = f+1; j < 10; j++) {
res+=cnt[j];
}
cnt[f]++;
}
return res;
}
static class Node {
long revnum;
String num;
public Node() {
// TODO Auto-generated constructor stub
}
public Node(long revnum, String num) {
this.revnum = revnum;
this.num = num;
}
}
}
宝石塔的亮度差异
问题描述
丽丽的家里建了两座宝石塔高度为 NN 的宝石塔,宝石塔每一层都有一颗独特的宝石,且宝石的亮度各不相同。
阿鹏决定美化这些宝石。他可以在两个宝石塔的任意两层交换宝石,交换的次数没有限制。他想通过交换,使得他收集到的第一个宝石塔的宝石亮度差异(最亮的宝石的亮度减去最暗的宝石的亮度)尽可能小。
请你帮助阿鹏,找出最小的亮度差异值。
输入格式
第一行输入一个整数 NN(1≤N≤1031≤N≤103),表示两座宝石塔的层数。
第二行输入 NN 个空格分隔的整数 A1,A2,...,ANA1,A2,...,AN(1≤Ai≤1051≤Ai≤105),表示第一个宝石塔每一层宝石的亮度。
第三行输入 NN 个空格分隔的整数 B1,B2,...,BNB1,B2,...,BN(1≤Bi≤1051≤Bi≤105),表示第二个宝石塔每一层宝石的亮度。
输出格式
输出一行,表示最小的亮度差异值。
样例输入
4
2 1 4 3
3 2 6 2
样例输出
1
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class Main {
static Map<Integer, Integer> map=new HashMap<Integer, Integer>();
static int N=2*1010,idx;//res=0;
static int a[]=new int[N];
//static int b[]=new int[N];
public static void main(String[] args) throws IOException {
//System.out.println(100);
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int n=Integer.parseInt(br.readLine());
String g[]=br.readLine().split(" ");
for (int i = 0; i < n; i++) {
a[i]=Integer.parseInt(g[i]);
}
g=br.readLine().split(" ");
for (int i = 0; i < n; i++) {
a[n+i]=Integer.parseInt(g[i]);
}
Arrays.sort(a,0,2*n);
int res=Integer.MAX_VALUE;
for (int i = 0; i <= n; i++) {
res=Math.min(a[i+n-1]-a[i], res);
}
System.out.println(res);
}
}
折半搜索

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
public class Main {
static Map<Long, Integer> map=new HashMap<>();
static int N=100,idx;
static boolean res=false;
static long v[]=new long[N];
static long w[]=new long[N];
//static long a[]=new long[N];
public static void main(String[] args) throws IOException {
//System.out.println(100);
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
//int n=Integer.parseInt(br.readLine());
String g[]=br.readLine().split(" ");
int n=Integer.parseInt(g[0]);
long s=Long.parseLong(g[1]);
g=br.readLine().split(" ");
int n1=n/2,n2=n-n1;
for (int i = 0; i < n1; i++) {
v[i]=Long.parseLong(g[i]);
//System.out.print(v[i]+" ");
}
for (int i = 0; i < n2; i++) {
w[i]=Long.parseLong(g[n1+i]);
//System.out.print(w[i]+" ");
}
dfs1(0,0,n1);
dfs2(0,0,n2,s);
if(res==true){
System.out.println("Yes");
}else{
System.out.println("No");
}
}
static void dfs1(int k,long sum,int n){
if(k>=n){
map.put(sum, map.getOrDefault(sum, 0)+1);
return;
}
dfs1(k+1, sum+v[k], n);
dfs1(k+1, sum, n);
}
static void dfs2(int k,long sum,int n,long s){
if(k>=n){
if(map.containsKey(s-sum))res=true;
return;
}
dfs2(k+1, sum+w[k], n,s);
dfs2(k+1, sum, n,s);
}
}
寻找食物储量
问题描述
你是一个冒险家,在一个危机四伏的森林里,你发现了一个隐藏的食物仓库。这个食物仓库由 nn 个房间组成,每个房间都有一定数量的食物。你需要找到第一个房间,其中的食物数量大于或等于一个给定的值 xx。
这些房间是按食物数量升序排列的。你知道每个房间的食物数量,但由于时间紧迫,你不能一个个房间地去查找。因此,你决定使用二分搜索来快速找到目标房间。
你的任务是编写一个程序,根据每个房间的食物数量和目标值 xx,输出第一个食物数量大于或等于 xx 的房间的编号。
输入格式
第一行包含一个整数 nn,(1≤n≤105)(1≤n≤105),表示房间的数量。
第二行包含 nn 个整数,表示每个房间的食物数量。这些整数是非降序排列的。
第三行包含一个整数 xx,(1≤x≤109)(1≤x≤109),表示目标食物数量。
输出格式
输出一个整数,表示第一个食物数量大于或等于 xx 的房间的编号。如果所有房间的食物数量都小于 xx,则输出 −1−1。
样例输入
5
2 5 8 10 15
9
样例输出
4
样例说明
在上述例子中,房间 44 的食物数量为 1010,这是第一个大于或等于 99 的值。
测评数据规模
对于 100100% 的数据,1≤n≤1061≤n≤106,并且每个房间的食物数量不超过 109109。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
public class Main {
static Map<Long, Integer> map=new HashMap<>();
static int N=1000010,idx;
static boolean res=false;
static int a[]=new int[N];
public static void main(String[] args) throws IOException {
//System.out.println(100);
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int n=Integer.parseInt(br.readLine());
String g[]=br.readLine().split(" ");
int x=Integer.parseInt(br.readLine());
for (int i = 0; i <n; i++) {
a[i]=Integer.parseInt(g[i]);
}
int l=0,r=n-1;
while(l<r){
int mid=(l+r)>>1;
if(a[mid]>=x){
r=mid;
}else{
l=mid+1;
}
}
if(a[l]>=x){
System.out.println(l+1);
}else{
System.out.println(-1);
}
}
}