1.打酱油
问题描述
小明带着N元钱去买酱油。酱油10块钱一瓶,商家进行促销,每买3瓶送1瓶,或者每买5瓶送2瓶。请问小明最多可以得到多少瓶酱油。
输入格式
输入的第一行包含一个整数N,表示小明可用于买酱油的钱数。N是10的整数倍,N不超过300。
输出格式
输出一个整数,表示小明最多可以得到多少瓶酱油。
样例输入
40
样例输出
5
样例说明
把40元分成30元和10元,分别买3瓶和1瓶,其中3瓶送1瓶,共得到5瓶。
样例输入
80
样例输出
11
样例说明
把80元分成30元和50元,分别买3瓶和5瓶,其中3瓶送1瓶,5瓶送2瓶,共得到11瓶。
Java代码
import java.util.*;
public class Main2017091 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n=scan.nextInt();
int res = 0;
n = n/10;
int x5 = n/5;
int x3 = (n-x5*5)/3;
res = x5*5+x5*2+x3*3+x3+(n-x5*5-x3*3);
System.out.print(res);
}
}
2.公共钥匙盒
问题描述
有一个学校的老师共用N个教室,按照规定,所有的钥匙都必须放在公共钥匙盒里,老师不能带钥匙回家。每次老师上课前,都从公共钥匙盒里找到自己上课的教室的钥匙去开门,上完课后,再将钥匙放回到钥匙盒中。
钥匙盒一共有N个挂钩,从左到右排成一排,用来挂N个教室的钥匙。一串钥匙没有固定的悬挂位置,但钥匙上有标识,所以老师们不会弄混钥匙。
每次取钥匙的时候,老师们都会找到自己所需要的钥匙将其取走,而不会移动其他钥匙。每次还钥匙的时候,还钥匙的老师会找到最左边的空的挂钩,将钥匙挂在这个挂钩上。如果有多位老师还钥匙,则他们按钥匙编号从小到大的顺序还。如果同一时刻既有老师还钥匙又有老师取钥匙,则老师们会先将钥匙全还回去再取出。
今天开始的时候钥匙是按编号从小到大的顺序放在钥匙盒里的。有K位老师要上课,给出每位老师所需要的钥匙、开始上课的时间和上课的时长,假设下课时间就是还钥匙时间,请问最终钥匙盒里面钥匙的顺序是怎样的?输入格式
输入的第一行包含两个整数N, K。
接下来K行,每行三个整数w, s, c,分别表示一位老师要使用的钥匙编号、开始上课的时间和上课的时长。可能有多位老师使用同一把钥匙,但是老师使用钥匙的时间不会重叠。
保证输入数据满足输入格式,你不用检查数据合法性。输出格式
输出一行,包含N个整数,相邻整数间用一个空格分隔,依次表示每个挂钩上挂的钥匙编号。
样例输入
5 2
4 3 3
2 2 7样例输出
1 4 3 2 5
样例说明
第一位老师从时刻3开始使用4号教室的钥匙,使用3单位时间,所以在时刻6还钥匙。第二位老师从时刻2开始使用钥匙,使用7单位时间,所以在时刻9还钥匙。
每个关键时刻后的钥匙状态如下(X表示空):
时刻2后为1X345;
时刻3后为1X3X5;
时刻6后为143X5;
时刻9后为14325。样例输入
5 7
1 1 14
3 3 12
1 15 12
2 7 20
3 18 12
4 21 19
5 30 9样例输出
1 2 3 5 4
评测用例规模与约定
对于30%的评测用例,1 ≤ N, K ≤ 10, 1 ≤ w ≤ N, 1 ≤ s, c ≤ 30;
对于60%的评测用例,1 ≤ N, K ≤ 50,1 ≤ w ≤ N,1 ≤ s ≤ 300,1 ≤ c ≤ 50;
对于所有评测用例,1 ≤ N, K ≤ 1000,1 ≤ w ≤ N,1 ≤ s ≤ 10000,1 ≤ c ≤ 100。
思路
这道题虽然是第二题,但是写了很久。主要是不知道怎样处理借和还的过程。解题思路如下。
首先需要接收输入的钥匙编号w、开始上课时间s、上课时长c等信息,并定义了一个结束时间e,判断对应的钥匙在哪个时间点归还。
定义一个时间计数器time,记录当前时刻。并从e中找到最后一个归还钥匙的时刻。
分析题目可以知道,主要过程包含了借钥匙和换钥匙两部分。首先在同一时间,先还再借。其次,借钥匙就是将钥匙序列中借走的钥匙置为空(0);还钥匙就需要依次按照归还的时间加入要归还钥匙的序列,同一时间归还钥匙,要按编号从小到大还。因此需要将待归还的钥匙从小到大排序。再从左至右归还。
循环条件即,当前时间小于等于最后一把钥匙的归还时间。否则就结束循环,输出当前的钥匙序列。
Java代码
import java.util.*;
public class Main2017092 {
public static void main(String [] args) {
Scanner scan = new Scanner(System.in);
int n=scan.nextInt();
int k = scan.nextInt();
int [] w = new int [k];//钥匙编号
int [] s = new int [k];//开始上课时间
int [] c = new int [k];//上课时长
int [] e = new int [k];//结束时间
for(int i =0;i<k;i++) {
w[i] = scan.nextInt();
s[i] = scan.nextInt();
c[i] = scan.nextInt();
e[i] = s[i]+c[i];
}
int [] seq = new int [n];//钥匙序列
for(int i=0;i<n;i++) {
seq[i] = i+1;
}
int time=1;//计时器
ArrayList<Integer> reb = new ArrayList<>();
int maxtime = 0;
for(int i=0;i<k;i++) {
if(maxtime < e[i])
maxtime =e[i];
}
while(time<=maxtime) {
re(n,k,w,s,e,time,reb,seq);
bo(n,k,w,s,e,time,reb,seq);
time++;
}
for(int i=0;i<n;i++) {
System.out.print(seq[i]+" ");
}
}
public static void re(int n,int k,int [] w,int [] s,int [] e,int time,ArrayList<Integer> reb,int [] seq) {
reb.clear();
for(int i=0;i<k;i++) {
if(e[i]==time) {
reb.add(w[i]);
}
}
if(reb.isEmpty()) {
return;
}else {
Collections.sort(reb);
for(int i=0,j=0;i<n;i++) {
if(seq[i]==0) {
seq[i] = reb.get(j) ;
if(reb.size()==j+1) {
break;
}else j++;
}
}
}
}
public static void bo(int n,int k,int [] w,int [] s,int [] e,int time,ArrayList<Integer> reb,int [] seq) {
for(int i=0;i<k;i++) {
if(s[i]==time) {
for(int j=0;j<n;j++) {
if(w[i]==seq[j]) {
seq[j]=0;
break;
}
}
}
}
}
}
3.Json查询
问题描述
JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式,可以用来描述半结构化的数据。JSON 格式中的基本单元是值 (value),出于简化的目的本题只涉及 2 种类型的值:
* 字符串 (string):字符串是由双引号 " 括起来的一组字符(可以为空)。如果字符串的内容中出现双引号 ",在双引号前面加反斜杠,也就是用 \" 表示;如果出现反斜杠 \,则用两个反斜杠 \\ 表示。反斜杠后面不能出现 " 和 \ 以外的字符。例如:""、"hello"、"\"\\"。
* 对象 (object):对象是一组键值对的无序集合(可以为空)。键值对表示对象的属性,键是属性名,值是属性的内容。对象以左花括号 { 开始,右花括号 } 结束,键值对之间以逗号 , 分隔。一个键值对的键和值之间以冒号 : 分隔。键必须是字符串,同一个对象所有键值对的键必须两两都不相同;值可以是字符串,也可以是另一个对象。例如:{}、{"foo": "bar"}、{"Mon": "weekday", "Tue": "weekday", "Sun": "weekend"}。
除了字符串内部的位置,其他位置都可以插入一个或多个空格使得 JSON 的呈现更加美观,也可以在一些地方换行,不会影响所表示的数据内容。例如,上面举例的最后一个 JSON 数据也可以写成如下形式。
{
"Mon": "weekday",
"Tue": "weekday",
"Sun": "weekend"
}
给出一个 JSON 格式描述的数据,以及若干查询,编程返回这些查询的结果。输入格式
第一行是两个正整数 n 和 m,分别表示 JSON 数据的行数和查询的个数。
接下来 n 行,描述一个 JSON 数据,保证输入是一个合法的 JSON 对象。
接下来 m 行,每行描述一个查询。给出要查询的属性名,要求返回对应属性的内容。需要支持多层查询,各层的属性名之间用小数点 . 连接。保证查询的格式都是合法的。输出格式
对于输入的每一个查询,按顺序输出查询结果,每个结果占一行。
如果查询结果是一个字符串,则输出 STRING <string>,其中 <string> 是字符串的值,中间用一个空格分隔。
如果查询结果是一个对象,则输出 OBJECT,不需要输出对象的内容。
如果查询结果不存在,则输出 NOTEXIST。样例输入
10 5
{
"firstName": "John",
"lastName": "Smith",
"address": {
"streetAddress": "2ndStreet",
"city": "NewYork",
"state": "NY"
},
"esc\\aped": "\"hello\""
}
firstName
address
address.city
address.postal
esc\aped样例输出
STRING John
OBJECT
STRING NewYork
NOTEXIST
STRING "hello"评测用例规模与约定
n ≤ 100,每行不超过 80 个字符。
m ≤ 100,每个查询的长度不超过 80 个字符。
字符串中的字符均为 ASCII 码 33-126 的可打印字符,不会出现空格。所有字符串都不是空串。
所有作为键的字符串不会包含小数点 .。查询时键的大小写敏感。
50%的评测用例输入的对象只有 1 层结构,80%的评测用例输入的对象结构层数不超过 2 层。举例来说,{"a": "b"} 是一层结构的对象,{"a": {"b": "c"}} 是二层结构的对象,以此类推。
思路
这是一道典型的字符串处理的题目,解题思路如下。
首先我们可以发现,输入的JSON字符串按照每行接收是无法判断多层数据的结构的,因此首先将所有的json的输入去掉所有换行和空格合并为一个字符串。再对这个字符串进行处理。
由于Json字符串中具有层级关系,我们首先定义一个level变量,存储当前是第几层,并用elem数组存储对应层级的根节点是什么。
下面用switch语句依次判断是键还是值。以键值对的方式存储在map集合中。
主要规则是,如果是“ 开头的,并且前面没 有:,那么遇到”时,键值取完,进行存储。遇到:时,从“开始,存储键对应的值。如果遇到{,则说明进入了新的一层,level+1,并且当前这层的根节点是elem[level-1],直接将当前元素的键值按“根节点.键值”的方式存储到键值对中,因此当多层元素查询的时候,可以直接通过键值匹配 .运算符。
Java代码
import java.util.*;
public class Main2017093 {
public static void main(String [] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int m = scan.nextInt();
scan.nextLine();
String [] rule = new String [m];
String s = "";
for(int i=0;i<n;i++) {
s=s+scan.nextLine().replaceAll("\\n", "").replaceAll(" ", "");
}
for(int i=0;i<m;i++) {
rule[i] = scan.nextLine();
}
boolean iskey = true;
int level = 0;
HashMap<String,String> map = new HashMap<>();
String [] elems = new String [100] ;
elems[0] = "root";
String key = "",value = "";
for(int i=1;i<s.length();i++) {
switch(s.charAt(i)) {
case '"':
String str = "";
boolean temp = true;
while(temp) {
i++;
switch(s.charAt(i)) {
case '\\'://转义字符只跳过一个
i++;
str+=s.charAt(i);
break;
case '"':
temp = false;
break;
default:
str+=s.charAt(i);
break;
}
}
if(iskey) {
key = str;
if(level>0) {
key = elems[level-1]+"."+key;
}
}else {
value = str;
map.put(key, "STRING"+" "+value);
}
break;
case ':':
iskey = false;
break;
case ',':
iskey = true;
break;
case '{':
elems[level]=key;
map.put(key, "OBJECT");
level++;
iskey = true;
break;
case '}':
level--;
break;
}
}
String [] res =new String [m];
for(int j=0;j<m;j++) {
if(map.get(rule[j])==null) {
res[j] = "NOTEXIST";
}else {
res[j] = map.get(rule[j]);
}
}
for(int j=0;j<m;j++) {
System.out.println(res[j]);
}
}
}