试题编号: | 201709-2 |
试题名称: | 公共钥匙盒 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 有一个学校的老师共用N个教室,按照规定,所有的钥匙都必须放在公共钥匙盒里,老师不能带钥匙回家。每次老师上课前,都从公共钥匙盒里找到自己上课的教室的钥匙去开门,上完课后,再将钥匙放回到钥匙盒中。 输入格式 输入的第一行包含两个整数N, K。 输出格式 输出一行,包含N个整数,相邻整数间用一个空格分隔,依次表示每个挂钩上挂的钥匙编号。 样例输入 5 2 样例输出 1 4 3 2 5 样例说明 第一位老师从时刻3开始使用4号教室的钥匙,使用3单位时间,所以在时刻6还钥匙。第二位老师从时刻2开始使用钥匙,使用7单位时间,所以在时刻9还钥匙。 样例输入 5 7 样例输出 1 2 3 5 4 评测用例规模与约定 对于30%的评测用例,1 ≤ N, K ≤ 10, 1 ≤ w ≤ N, 1 ≤ s, c ≤ 30; |
java:(100分通过)
法一:只用二维数组排序
转载自 https://blog.youkuaiyun.com/qq_26580757/article/details/78513540
其中:多维数组按某列排序可参看https://www.cnblogs.com/whaozl/p/4061993.html
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class Main {
static int res[];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
int a[][] = new int[k][3];
for (int i = 0; i < a.length; i++) {
a[i][0] = sc.nextInt();
a[i][1] = sc.nextInt();
a[i][2] = sc.nextInt()+a[i][1];
}
int as[][] = a.clone();
int ae[][] = a.clone();
Sort(as,1);
Sort(ae,2);
res = new int[n+1];
for (int i = 1; i < res.length; i++) {
res[i] = i;
}
int t = 0;
int s = 0,e = 0;
while((t++)<10101){//10001不够,只有70分;所以记得加上上课时间c,最长为100;
for (; e < ae.length; e++) {
if(t<ae[e][2]) break;
if(t==ae[e][2]){
PBack(ae[e][0]);
}
}
for (; s < as.length; s++) {
if(t<as[s][1]) break;
if(t==as[s][1]){
Use(as[s][0]);
}
}
if(s==as.length&&e==ae.length) break;
}
ShowAns();
}
private static void PBack(int name) {
for (int i = 1; i < res.length; i++) {
if(res[i] == -1){
res[i] = name;
break;
}
}
}
private static void Use(int name) {
for (int i = 1; i < res.length; i++) {
if(res[i] == name){
res[i] = -1;
break;
}
}
}
private static void Sort(int[][] a,int i) {
Arrays.sort(a,new Comparator<int[]>(){
public int compare(int[] o1, int[] o2) {
if(o1[i]==o2[i]) return o1[0]-o2[0];
return o1[i]-o2[i] ;
}
});
}
public static void ShowAns(){
for (int i = 1; i < res.length; i++) {
System.out.print(res[i]+" ");
}
System.out.println();
}
}
法二:
转载自:https://blog.youkuaiyun.com/hunjue0915/article/details/80670903
import java.util.*;
public class Main {
static int time=1,maxtime=0,keynum;
static int[] keylist;
static List<Teacher> teacherList=new ArrayList<>();
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
keynum=in.nextInt();
int teachernum=in.nextInt();
for(int i=0;i<teachernum;i++){
int key=in.nextInt();
int s=in.nextInt();
int c=in.nextInt();
if (s+c>maxtime){
maxtime=s+c;
}
Teacher teacher=new Teacher(key,s,s+c);
teacherList.add(teacher);
}
keylist=new int[keynum];
for (int i=0;i<keynum;i++){
keylist[i]=i+1;
}
while (time<=maxtime){
returnkey();
getkey();
time++;
}
for (int i=0;i<keylist.length;i++){
System.out.print(keylist[i]+" ");
}
}
private static void getkey() {
for (int i=0;i<teacherList.size();i++){
if (teacherList.get(i).s==time){
int temp=teacherList.get(i).key;
for (int j=0;j<keylist.length;j++){
if (keylist[j]==temp){
keylist[j]=0;
}
}
}
}
}
private static void returnkey() {
List<Integer> returnlist=new ArrayList<>();
for (int i=0;i<teacherList.size();i++){
int temp=teacherList.get(i).end;
if (temp==time){
returnlist.add(teacherList.get(i).key);
}
}
if (returnlist.isEmpty()){
return;
}else {
//将要归还的钥匙从小到大排序
for (int i = 0; i < returnlist.size() - 1; i++) {
for (int j = 0; j < returnlist.size() - 1 - i; j++) {
if (returnlist.get(j) > returnlist.get(j + 1)) {
int temp = returnlist.get(j);
returnlist.set(j, returnlist.get(j + 1));
returnlist.set(j + 1, temp);
}
}
}
}
int m=0;
for (int i=0;i<keylist.length;i++){
if (keylist[i]==0){
keylist[i]=returnlist.get(m);
if (m<returnlist.size()-1){
m++;
}else {
break;
}
}
}
}
static class Teacher{
int key,s,end;
public Teacher(int key, int s, int end) {
this.key = key;
this.s = s;
this.end = end;
}
}
}
c++:
#include<bits/stdc++.h>
using namespace std;
//发生事件的结构体
class node{
public:
int bt;//发生的时间
int key;//钥匙编号
int act;//借或者换,表示为1和0
};
//排序函数,按时间、动作、钥匙编号升序排列
bool cmpnode(const node &a,const node &b){
if(a.bt!=b.bt) return a.bt<b.bt;
if(a.act!=b.act) return a.act<b.act;
return a.key<b.key;
}
int main(){
int n,k; cin>>n>>k;
// 产生钥匙盒与事件数组
int *keys=new int[n];
node *acts=new node[2*k];
// 初始化钥匙盒数组
for(int i=0;i<n;i++)
keys[i]=i+1;
// 读取上下课时间,拆分为取和换钥匙事件
for(int i=0;i<k;i++){
int w, s, c;cin>>w>>s>>c;
acts[2*i].key=w;
acts[2*i].bt=s;
acts[2*i].act=1;
acts[2*i+1].key=w;
acts[2*i+1].bt=s+c;
acts[2*i+1].act=0;
}
// 多条件排序(时间、动作、钥匙编号)
sort(acts,acts+2*k,cmpnode);
for(int i=0;i<2*k;i++){
if(acts[i].act==1){//取钥匙 key->0
for(int j=0;j<n;j++){
if(keys[j]==acts[i].key){
keys[j]=0;
break;
}
}
}
else{ //还钥匙 0->key
for(int j=0;j<n;j++){
if(keys[j]==0){
keys[j]=acts[i].key;
break;
}
}
}
}
// 打印输出
for(int i=0;i<n;i++){
cout<<keys[i];
if(i!=n-1) cout<<" ";//特殊处理最后一个钥匙
}
// 删除动态数组
delete []acts;
delete []keys;
return 0;
}