题目描述
在市场上有很多商品的定价类似于 999 元、4999 元、8999 元这样。它们和 1000 元、5000 元和 9000 元并没有什么本质区别,但是在心理学上会让人感觉便宜很多,因此也是商家常用的价格策略。不过在你看来,这种价格十分荒谬。于是你如此计算一个价格 pp(pp 为正整数)的荒谬程度:
- 首先将 pp 看做一个由数字组成的字符串(不带前导 00);
- 然后,如果 pp 的最后一个字符是 00,就去掉它。重复这一过程,直到 pp 的最后一个字符不是 00;
- 记 pp 的长度为 aa,如果此时 pp 的最后一位是 55,则荒谬程度为 2a - 12a−1;否则为 2a2a。
例如,850850 的荒谬程度为 33,而 880880 则为 44,99999999 的荒谬程度为 88。
现在,你要出售一样闲置物品,你能接受的定价在 [L, R][L,R] 范围内,你想要给出一个荒谬度最低的价格。
输入格式
输入文件的第一行包含一个正整数 TT,表示测试数据的数目。
每个测试数据占单独的一行,包含两个空格分隔的正整数 L, RL,R,表示定价的区间。
输出格式
对于每个测试数据,在单独的一行内输出结果。如果荒谬度最低的价格不唯一,输出最小的那个。
样例
Inputcopy | Outputcopy |
---|---|
3 998 1002 998 2002 4000 6000 | 1000 1000 5000 |
数据范围与提示
对于 100 \%100% 的数据,T \leq 100, \ 1 \leq L \leq R \leq 10^9T≤100, 1≤L≤R≤109。
思路:我们只需要枚举L-R之间的数就好了,但是450-459的荒谬度都是3,1000-1999的荒谬du都是2,所以我们可以对枚举进行简单的优化,并且荒谬度最小为一,只要出现了荒谬度为一的一个数,那么我们就可以确定他一定是最优的了。又是一步优化~
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner cin=new Scanner(System.in);
int t=cin.nextInt();
while(t-->0) {
int l=cin.nextInt();
int r=cin.nextInt();
int ans=0,imin=(int) 1e9;
while(l<=r) {
//进行优化枚举
int x=l,cnt=0;
while(x%10==0) {
x/=10;
cnt++;
}
//荒谬度计算并判断·
int sum=String.valueOf(x).length()*2;
if(x%5==0)sum--;
if(sum<imin) {
ans=l;imin=sum;
if(ans==1)break;
}
l+=Math.pow(10, cnt);
}
System.out.println(ans);
}
}
}
n个人一起排队接水,第i个人需要b[i]的时间来接水。(1<=n<=1000,0<=b[i]<=1000)
同时只能有一个人接水,正在接水的人和没有接水的人都需要等待。
完成接水的人会立刻消失,不会继续等待。
你可以决定所有人接水的顺序,并希望最小化所有人等待时间的总和。
Input
第一行一个整数n 接下来n行,每行一个整数表示b[i]
Output
一行一个整数,表示所有人等待时间的总和的最小值
Sample
Inputcopy | Outputcopy |
---|---|
3 1 2 3 | 10 |
思路:因为要使所有人的等待时间之和最短,那么就需要每个人的等待时间最短,我们只要让较短时间接水的人排在前面就好了。
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner cin=new Scanner(System.in);
int n=cin.nextInt();
int b[]=new int[n];
int ans=0;
for(int i=0;i<n;i++) {
b[i]=cin.nextInt();
}
Arrays.sort(b);
ans+=b[0];
for(int i=1;i<n;i++) {
b[i]+=b[i-1];
ans+=b[i];
}
System.out.println(ans);
}
}
N - 接水问题二
n 个人一起排队接水,第 ii 个人的重要性是 a[i]a[i],需要 b[i]b[i] 的时间来接水。(1 <= n <= 100000,0 <= b[i] <= 1000,0 <= a[i] <= 1000)
同时只能有一个人接水,正在接水的人和没有接水的人都需要等待。
完成接水的人会立刻消失,不会继续等待。
你可以决定所有人接水的顺序,并希望最小化所有人等待时间乘以自己的重要性 a[i]a[i] 的总和,输出等待时间乘以自己的重要性的总和。
Input
第一行一个整数n。 以下n行,每行两个整数a[i]和b[i]。
Output
一行一个整数表示答案。
Sample
Inputcopy | Outputcopy |
---|---|
4 1 4 2 3 3 2 4 1 |
注:记得将a[i]=0||b[i]=0的选项去掉,否则会导致运行错误
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
class l{
int a,b;
}
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner cin=new Scanner(System.in);
int n=cin.nextInt();
l a[]=new l[n+1];
a[0]=new l();
for(int i=1;i<=n;i++) {
a[i]=new l();
a[i].a=cin.nextInt();
a[i].b=cin.nextInt();
if(a[i].a==0||a[i].b==0) {
i--;n--;
}
}
//按照公式进行自定义排序,一定记住是排序1-n个你初始化好的数,否则也会报错
Arrays.sort(a,1,n+1,new Comparator<l>() {
public int compare(l o1,l o2) {
return o2.a*o1.b-o1.a*o2.b;
}
});
long ans=0,sum=0;
for(int i=1;i<=n;i++) {
sum+=a[i].b;
ans+=sum*a[i].a;
}
System.out.println(ans);
}
}