专题枚举模拟与排序
Posted Johnny*
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了专题枚举模拟与排序相关的知识,希望对你有一定的参考价值。
特别数的和
【题目描述】
AcWing 1245. 特别数的和
【思路】
位数分解
import java.util.Scanner;
public class Main{
public static boolean check(int x){
//分解位数
while(x > 0){
int t = x % 10;
//判断是否满足条件
if( t == 2|| t == 0|| t == 1 || t== 9) return true;
x /= 10;
}
return false;
}
public static void main(String args[]){
Scanner reader = new Scanner(System.in);
int n = reader.nextInt();
long ans = 0;
//枚举
for(int i = 1; i <= n ; i++){
if(check(i))
ans += i;
}
System.out.println(ans);
}
}
错误票据
【思路】
开一个数组cnt统计 各个数出现的次数
易知:因为重号不为最大和最小数,所以若i为重号则i次数为0,cnt[i - 1]必不为0
import java.io.*;
public class Main{
static int N = 100010;
static int cnt [] = new int [N];
public static void main(String args[]) throws Exception{
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(bf.readLine());
while(n -- > 0){
String s [] = bf.readLine().split("\\\\s+");//表示若干个空格
for(int i = 0; i < s.length; i ++)
cnt[ Integer.parseInt(s[i]) ]++;
}
//断号不可能发生在最大和最小号
// 0 1 1 1 0 1 0
int a = 1;
for(int i = 1; i < 100000; i ++){
if( cnt[i] == 0 && cnt[i - 1]!=0 ) {
a = i;
break;
}
}
int b = 3;
for(int i = 0; i < 100000; i ++)
if( cnt[i] > 1){
b = i;
break;
}
System.out.println(a+ " "+ b);
}
}
外卖店优先级
【思路】
状态压缩
st[i] 表示id号为i的店铺当前是否在优先队列中
score[i] 表示id号为 i的店铺当前的优先级
last[i] 表示id号为i的店铺上一次有订单的时刻
1、 将所有订单信息按(时间,店铺id)升序排序
2、 枚举所有订单,获得该店的所有订单q[i ~ j]
t时刻该店(id)有订单,订单数为 cnt =
处理t时刻前店铺的订单信息:
score[id] - = t -last[id] - 1;
if(score[id] < 0) score[id] = 0;
if(score[id] <= 3) st[id] =false;
last[id] = t;
处理t时刻该店铺有订单:
score[id] += cnt *2
if(score[id] >5) st[id] = true
if(t < T){//最后一段时间没有订单
score[id] -= T - last[id];
}
if(score[id] <= 3) st[id] = false;
import java.io.*;
import java.util.Arrays;
class order implements Comparable<order>{
int ts, id;
public order(int t, int i){
this.ts = t;
this.id = i;
}
//自定义排序:先按时间排序、再按id排序
public int compareTo(order o){
if(this.ts == o.ts) return this.id - o.id;//若时间相同则按店铺id升序排序
else return this.ts -o.ts; //按时间升序排序
}
public String toString(){
return this.ts+ " "+ this.id +"\\n";
}
}
public class Main{
static int N = 100010;
static order []q = new order[N];
static int [] score = new int[N]; //score[i]表示id号为i的店当前优先级
static int []last = new int[N]; //last[i]表示id号为i的店最近一次有订单的时刻
static boolean [] st = new boolean[N]; //st[i]表示id号为i的店当前在不在优先级队列中
public static void main(String agrs[]) throws Exception{
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
String s[] = bf.readLine().split(" ");
int n = Integer.parseInt(s[0]),m = Integer.parseInt(s[1]), T = Integer.parseInt(s[2]);
for(int i = 0; i < m; i ++){
String str[] = bf.readLine().split(" ");
q[i] = new order(Integer.parseInt(str[0]), Integer.parseInt(str[1]));
}
Arrays.sort(q,0, m );
System.out.println(Arrays.toString(q));
for(int i = 0; i < m; ){
int j = i;
while(j < m && q[j]== q[i]) j ++; // 相同(ts、id皆相同)订单
int t = q[i].ts, id = q[i].id, cnt = j - i;
i = j;
//处理一批相同的订单
score[id] = score[id] - t - last[id] - 1;//处理t时刻前订单,有(t -last[id]-1)个时刻没有订单
if(score[id] < 0) score[id] = 0;
if(score[id] <= 3) st[id] = false;
score[id] += cnt *2; //处理t时刻订单
if(score[id] > 5) st[id] = true;
last[id] = t;
//处理下一批订单
}
//最后一段没有订单
for(int i = 1; i <= n; i ++){
if(last[i] < T){
score[i] = score[i] - T - last[i];
if(score[i] <= 3) st[i] = false;
}
}
int ans = 0;
for(int i = 1; i <= n; i ++)
if(st[i]) ans++;
System.out.println(ans);
}
}
【题目描述】
【思路】
做完才发现其实可以预处理 都减去1 哭了
一堆边界判断
import java.util.Scanner;
import java.lang.Math;
class Main{
public static int get_y(int row, int w, int x){
//根据规律 行数为偶数则从左到右递增
int y = 0;
if( (row & 1) == 0 ) y = (x % w == 0? w:x % w);
else y = w - x % w + 1;
return y;
}
public static void main(String args[]){
Scanner reader = new Scanner(System.in);
int w = reader.nextInt(), m = reader.nextInt(), n = reader.nextInt();
//注意处理边界
//计算两个数的位置
int x1 = m / w + (m % w == 0? -1: 0), x2 = n / w + (n % w == 0? -1: 0);
int y1 = get_y(x1, w, m), y2 = get_y(x2, w, n);
//System.out.println(x1+" "+y1);
//System.out.println(x2+" "+y2);
//计算移动距离
int res = Math.abs(x1 - x2) + Math.abs(y1 - y2);
System.out.println(res);
}
}
以上是关于专题枚举模拟与排序的主要内容,如果未能解决你的问题,请参考以下文章