1.小中大
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n=scan.nextInt();
int i,max,min;
double mid;
int[] arr = new int[n];
for(i=0;i<n;i++){
arr[i]=scan.nextInt();
}
max=arr[0];
min=arr[0];
for(i=0;i<n;i++){
if(arr[i]>max)
max=arr[i];
if(arr[i]<min)
min=arr[i];
}
System.out.print(max);
System.out.print(" ");
if(n%2==0){
mid=(arr[arr.length/2]+arr[(arr.length-2)/2])/(2.0);
if((arr[arr.length/2]+arr[(arr.length-2)/2])%2==0) {
System.out.print((int)mid);
System.out.print(" ");
}else {
System.out.print(mid);
System.out.print(" ");
}
}else{
mid=arr[arr.length/2];
System.out.print((int)mid);
System.out.print(" ");
}
System.out.print(min);
System.out.print(" ");
}
}
2.二十四点
其实就是四则运算,用到了数据结构栈的知识来解决
思路是:中缀表达式转后缀表达式(需要定义一个操作符栈),再对后缀表达式进行计算(需要定义一个操作数栈)
转换规则:
中缀转后缀:
1.数字直接输出成为后缀表达式的一部分
2.非数字,若栈内空则压栈
3.当前输入的操作符比栈顶元素的优先则压栈
4.不优先(包含等于)则顶部元素一直出栈,直到栈顶元素比当前元素优先才停止出栈,若是右括号,则出栈遇到左括号停止,括号成对消失
对后缀表达式计算:
1.遇到数字则压栈
2.遇到符号则弹栈,弹两次,分别作为右操作数和左操作数,并将计算的结果压栈
import java.util.*;
public class Main{
public static void main(String[] args) {
Stack<Character> priStack = new Stack<Character>();// 操作符栈
Scanner scan = new Scanner(System.in);
int n=scan.nextInt();
int i,k;
String buf=new String();//输出的后缀表达式
String temp=new String();//用于暂存输入的中缀表达式
String[] arr = new String[n];//字符串数组,用于存放转化后的后缀表达式
//中缀表达式转化为后缀表达式
//数字直接输出->
//非数字,栈内空压栈->
//当前输入的操作符比栈顶元素的优先则压栈->
//不优先(包含等于)则顶部元素一直出栈,直到栈顶元素比当前元素优先才停止出栈
for(i=0;i<n;i++) {
temp=scan.next();
buf="";
char d;
for(k=0;k<7;k++) {
char ch=temp.charAt(k);
if(ch>='1'&&ch<='9') {
buf=buf+ch;
}else if (priStack.empty()==true) {
priStack.push(ch);
}else if(getprio(ch)<getprio(d=(priStack.peek()))) {
priStack.push(ch);
}else {
while(priStack.empty()==false) {
if(getprio(priStack.peek())<=getprio(ch)) {
buf+=priStack.peek();
priStack.pop();
}
else
break;
}
priStack.push(ch);
}
}
while(priStack.empty()==false) {
buf+=priStack.pop();
}
arr[i]=buf;
}
for(i=0;i<n;i++) {
if(caculate(arr[i])==24) {
System.out.println("Yes");
}else {
System.out.println("No");
}
//System.out.println(arr[i]);//打印后缀表达式看看正确与否
//System.out.println(caculate(arr[i]));//计算结果
}
}
//根据算数符号获取优先级
public static int getprio(char oper) {
if(oper=='+'||oper=='-') {
return 1;
}else {
return 0;
}
}
//后缀表达式计算
public static int caculate(String str) {
int j;
int left,right,result;
Stack<Integer> numStack = new Stack<Integer>();// 操作数栈
for(j=0;j<7;j++) {
char ch=str.charAt(j);
if(ch>='0'&&ch<='9') {
numStack.push(ch-'0');
}else {
right=numStack.pop();
left=numStack.pop();
switch(ch) {
case '+':numStack.push(left+right);break;
case '-':numStack.push(left-right);break;
case 'x':numStack.push(left*right);break;
case '/':numStack.push(left/right);break;
}
}
}
result=numStack.pop();
return result;
}
}
3.小明上学
题目背景
小明是汉东省政法大学附属中学的一名学生,他每天都要骑自行车往返于家和学校。为了能尽可能充足地睡眠,他希望能够预计自己上学所需要的时间。他上学需要经过数段道路,相邻两段道路之间设有至多一盏红绿灯。
京州市的红绿灯是这样工作的:每盏红绿灯有红、黄、绿三盏灯和一个能够显示倒计时的显示牌。假设红绿灯被设定为红灯 r 秒,黄灯 y 秒,绿灯 g 秒,那么从 0 时刻起,[0,r) 秒内亮红灯,车辆不许通过;[r, r+g) 秒内亮绿灯,车辆允许通过;[r+g, r+g+y) 秒内亮黄灯,车辆不许通过,然后依次循环。倒计时的显示牌上显示的数字 l(l > 0)是指距离下一次信号灯变化的秒数。
问题描述
一次上学的路上,小明记录下了经过每段路的时间,和各个红绿灯在小明到达路口时的颜色和倒计时秒数。希望你帮忙计算此次小明上学所用的时间。
输入格式
输入的第一行包含空格分隔的三个正整数 r、y、g,表示红绿灯的设置。这三个数均不超过 106。
输入的第二行包含一个正整数 n(n ≤ 100),表示小明总共经过的道路段数和看到的红绿灯数目。
接下来的 n 行,每行包含空格分隔的两个整数 k、t。k=0 表示经过了一段道路,耗时 t 秒,此处 t 不超过 106;k=1、2、3 时,分别表示看到了一个红灯、黄灯、绿灯,且倒计时显示牌上显示的数字是 t,此处 t 分别不会超过 r、y、g。
输出格式
输出一个数字,表示此次小明上学所用的时间。
样例输入
30 3 30
8
0 10
1 5
0 11
2 2
0 6
0 3
3 10
0 3
样例输出
70
样例说明
小明先经过第一段道路,用时 10 秒,然后等待 5 秒的红灯,再经过第二段道路,用时 11 秒,然后等待 2 秒的黄灯和 30 秒的红灯,再经过第三段、第四段道路,分别用时6、3秒,然后通过绿灯,再经过最后一段道路,用时 3 秒。共计 10 + 5 + 11 + 2 + 30 + 6 + 3 + 3=70 秒。
评测用例规模与约定
测试点 1, 2 中不存在任何信号灯。
测试点 3, 4 中所有的信号灯在被观察时均为绿灯。
测试点 5, 6 中所有的信号灯在被观察时均为红灯。
测试点 7, 8 中所有的信号灯在被观察时均为黄灯。
测试点 9, 10 中将出现各种可能的情况。
这题就一个陷阱,等完黄灯还要等红灯
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int r=scan.nextInt();
int y=scan.nextInt();
int g=scan.nextInt();
int n=scan.nextInt();
int sum=0;
for(int i=0;i<n;i++) {
int k=scan.nextInt();
int t=scan.nextInt();
switch (k) {
case 0:
case 1:sum=sum+t;break;
case 2:sum=sum+t+r;break;
case 3:
}
}
System.out.println(sum);
}
}
4.小明放学
题目背景
汉东省政法大学附属中学所在的光明区最近实施了名为“智慧光明”的智慧城市项目。具体到交通领域,通过“智慧光明”终端,可以看到光明区所有红绿灯此时此刻的状态。小明的学校也安装了“智慧光明”终端,小明想利用这个终端给出的信息,估算自己放学回到家的时间。
问题描述
一次放学的时候,小明已经规划好了自己回家的路线,并且能够预测经过各个路段的时间。同时,小明通过学校里安装的“智慧光明”终端,看到了出发时刻路上经过的所有红绿灯的指示状态。请帮忙计算小明此次回家所需要的时间。
输入格式
输入的第一行包含空格分隔的三个正整数 r、y、g,表示红绿灯的设置。这三个数均不超过 106。
输入的第二行包含一个正整数 n,表示小明总共经过的道路段数和路过的红绿灯数目。
接下来的 n 行,每行包含空格分隔的两个整数 k、t。k=0 表示经过了一段道路,将会耗时 t 秒,此处 t 不超过 106;k=1、2、3 时,分别表示出发时刻,此处的红绿灯状态是红灯、黄灯、绿灯,且倒计时显示牌上显示的数字是 t,此处 t 分别不会超过 r、y、g。
输出格式
输出一个数字,表示此次小明放学回家所用的时间。
样例输入
30 3 30
8
0 10
1 5
0 11
2 2
0 6
0 3
3 10
0 3
样例输出
46
样例说明
小明先经过第一段路,用时 10 秒。第一盏红绿灯出发时是红灯,还剩 5 秒;小明到达路口时,这个红绿灯已经变为绿灯,不用等待直接通过。接下来经过第二段路,用时 11 秒。第二盏红绿灯出发时是黄灯,还剩两秒;小明到达路口时,这个红绿灯已经变为红灯,还剩 11 秒。接下来经过第三、第四段路,用时 9 秒。第三盏红绿灯出发时是绿灯,还剩 10 秒;小明到达路口时,这个红绿灯已经变为红灯,还剩两秒。接下来经过最后一段路,用时 3 秒。共计 10+11+11+9+2+3 = 46 秒。
评测用例规模与约定
有些测试点具有特殊的性质:
* 前 2 个测试点中不存在任何信号灯。
测试点的输入数据规模:
* 前 6 个测试点保证 n ≤ 103。
* 所有测试点保证 n ≤ 105。
主要思路参考这个:
例如:红灯15秒,绿灯20秒,黄灯10秒。在我们出发时有一个灯,是还剩10秒的红灯,在经过一段50秒的平路后到达这个红灯。首先,根据我上面定义的周期,这个红灯已经持续了15-10=5秒,然后50秒后到达这个红灯,此时这个灯已经花费了50+5=55秒。那么这个55就是从初始状态到小明到达这个灯时它所花费的时间,现在要确定这个灯的状态和所剩时间,用55取余一个周期的时间,即55%(15+20+10)=10。即到达这个灯时它的状态是还剩15-10=5秒的红灯。
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
long r=scan.nextInt();
long y=scan.nextInt();
long g=scan.nextInt();
int n=scan.nextInt();
long sum=0;
//long T=0;
for(int i=0;i<n;i++) {
int k=scan.nextInt();
long t=scan.nextInt();
long temp;
switch (k) {
//道路
case 0:sum=sum+t;break;
//红灯
case 1:{
temp=(r-t+sum)%(r+y+g);
if(temp>=0&&temp<r)
sum=sum+r-temp;
else if(temp>=r+g&&temp<r+g+y) {
sum=sum+r+g+y-temp+r;
}
break;
}
//黄灯
case 2:{
temp=(y-t+sum)%(r+y+g);
if(temp>=0&&temp<y)
sum=sum+y-temp+r;
else if(temp>=y&&temp<r+y) {
sum=sum+r+y-temp;
}
break;
}
//绿灯
case 3:{
temp=(g-t+sum)%(r+y+g);
if(temp>=g&&temp<g+y)
sum=sum+y+g-temp+r;
else if(temp>g+y&&temp<=r+y+g) {
sum=sum+r+y+g-temp;
}
break;
}
}
}
System.out.println(sum);
}
}
5.卖菜
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n=scan.nextInt();
int i;
int []arr=new int[n];
int []res=new int[n];
for(i=0;i<n;i++) {
arr[i]=scan.nextInt();
}
res[0]=(arr[0]+arr[1])/2;
res[n-1]=(arr[n-2]+arr[n-1])/2;
for(i=1;i<=n-2;i++) {
res[i]=(arr[i-1]+arr[i+1]+arr[i])/3;
}
for(i=0;i<n;i++) {
System.out.print(res[i]);
System.out.print(' ');
}
}
}
6.买菜
问题描述
小H和小W来到了一条街上,两人分开买菜,他们买菜的过程可以描述为,去店里买一些菜然后去旁边的一个广场把菜装上车,两人都要买n种菜,所以也都要装n次车。具体的,对于小H来说有n个不相交的时间段[a1,b1],[a2,b2]…[an,bn]在装车,对于小W来说有n个不相交的时间段[c1,d1],[c2,d2]…[cn,dn]在装车。其中,一个时间段[s, t]表示的是从时刻s到时刻t这段时间,时长为t-s。
由于他们是好朋友,他们都在广场上装车的时候会聊天,他们想知道他们可以聊多长时间。
输入格式
输入的第一行包含一个正整数n,表示时间段的数量。
接下来n行每行两个数ai,bi,描述小H的各个装车的时间段。
接下来n行每行两个数ci,di,描述小W的各个装车的时间段。
输出格式
输出一行,一个正整数,表示两人可以聊多长时间。
样例输入
4
1 3
5 6
9 13
14 15
2 4
5 7
10 11
13 14
样例输出
3
数据规模和约定
对于所有的评测用例,1 ≤ n ≤ 2000, ai < bi < ai+1,ci < di < ci+1,对于所有的i(1 ≤ i ≤ n)有,1 ≤ ai, bi, ci, di ≤ 1000000。
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n=scan.nextInt();
int i,j;
int sum=0;
int u=0;
int [][]arr1=new int[n][2];
int [][]arr2=new int[n][2];
for(i=0;i<n;i++) {
arr1[i][0]=scan.nextInt();
arr1[i][1]=scan.nextInt();
}
for(i=0;i<n;i++) {
arr2[i][0]=scan.nextInt();
arr2[i][1]=scan.nextInt();
}
for(i=0;i<n;i++) {
for(j=0;j<n;j++) {
u=Math.min(arr1[i][1], arr2[j][1])-Math.max(arr1[i][0], arr2[j][0]);
if(u>0)
sum+=u;
}
}
System.out.println(sum);
}
}
7.跳一跳
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n,sum;
sum=0;
int flag=0;
while( (n=scan.nextInt())!=0) {
if(n==1) {
flag=0;
sum=sum+1;
}else if(n==2) {
flag++;
sum=sum+2*flag;
}
}
System.out.println(sum);
}
}
8.碰撞的小球
问题描述
数轴上有一条长度为L(L为偶数)的线段,左端点在原点,右端点在坐标L处。有n个不计体积的小球在线段上,开始时所有的小球都处在偶数坐标上,速度方向向右,速度大小为1单位长度每秒。
当小球到达线段的端点(左端点或右端点)的时候,会立即向相反的方向移动,速度大小仍然为原来大小。
当两个小球撞到一起的时候,两个小球会分别向与自己原来移动的方向相反的方向,以原来的速度大小继续移动。
现在,告诉你线段的长度L,小球数量n,以及n个小球的初始位置,请你计算t秒之后,各个小球的位置。
提示
因为所有小球的初始位置都为偶数,而且线段的长度为偶数,可以证明,不会有三个小球同时相撞,小球到达线段端点以及小球之间的碰撞时刻均为整数。
同时也可以证明两个小球发生碰撞的位置一定是整数(但不一定是偶数)。
输入格式
输入的第一行包含三个整数n, L, t,用空格分隔,分别表示小球的个数、线段长度和你需要计算t秒之后小球的位置。
第二行包含n个整数a1, a2, …, an,用空格分隔,表示初始时刻n个小球的位置。
输出格式
输出一行包含n个整数,用空格分隔,第i个整数代表初始时刻位于ai的小球,在t秒之后的位置。
样例输入
3 10 5
4 6 8
样例输出
7 9 9
样例说明
样例输入
10 22 30
14 12 16 6 10 2 8 20 18 4
样例输出
6 6 8 2 4 0 4 12 10 2
数据规模和约定
对于所有评测用例,1 ≤ n ≤ 100,1 ≤ t ≤ 100,2 ≤ L ≤ 1000,0 < ai < L。L为偶数。
保证所有小球的初始位置互不相同且均为偶数。
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n=scan.nextInt();
int L=scan.nextInt();
int t=scan.nextInt();
int i,j,k,g;
Ball []arr=new Ball[n];
//初始化
for(i=0;i<n;i++) {
int x=scan.nextInt();
arr[i]=new Ball(x);
}
for(i=1;i<=t;i++) {
for(j=0;j<n;j++) {
//碰到边界改变方向
if(arr[j].getLoc()==L||arr[j].getLoc()==0) {
arr[j].changeDir();
}
//遍历每一个别的小球若碰撞改变方向
for(k=0;k<n;k++) {
if(arr[j].getLoc()==arr[k].getLoc()&&j!=k&&arr[j].getDir()!=arr[k].getDir()) {
arr[j].changeDir();
arr[k].changeDir();
}
}
//移动
arr[j].go();
}
}
for(g=0;g<n;g++) {
System.out.print(arr[g].getLoc());
System.out.print(" ");
}
}
}
//定义一个小球类
class Ball{
int loc,d;//小球的位置和方向
public Ball(int a){
this.loc=a;
this.d=1;
}
//获取小球位置
public int getLoc() {
return this.loc;
}
//获取小球方向
public int getDir() {
return this.d;
}
//改变方向
public void changeDir() {
if(this.d==1) {
this.d=0;
}else {
this.d=1;
}
}
//移动
public void go() {
if(this.d==1) {
this.loc++;
}else {
this.loc--;
}
}
}