模拟枚举排序

ACwing-1210. 连号区间数

小明这些天一直在思考这样一个奇怪而有趣的问题:

在 1∼N 的某个排列中有多少个连号区间呢?

这里所说的连号区间的定义是:

如果区间 [L,R] 里的所有元素(即此排列的第 L 个到第 R 个元素)递增排序后能得到一个长度为 R−L+1 的“连续”数列,则称这个区间连号区间。

当 N 很小的时候,小明可以很快地算出答案,但是当 N 变大的时候,问题就不是那么简单了,现在小明需要你的帮助。

输入格式
第一行是一个正整数 N,表示排列的规模。

第二行是 N 个不同的数字 Pi,表示这 N 个数字的某一排列。

输出格式
输出一个整数,表示不同连号区间的数目。

数据范围
1≤N≤10000,
1≤Pi≤N
输入样例1:
4
3 2 4 1
输出样例1:
7
输入样例2:
5
3 4 2 5 1
输出样例2:
9
样例解释
第一个用例中,有 7 个连号区间分别是:[1,1],[1,2],[1,3],[1,4],[2,2],[3,3],[4,4]
第二个用例中,有 9 个连号区间分别是:[1,1],[1,2],[1,3],[1,4],[1,5],[2,2],[3,3],[4,4],[5,5]

ps : 第二行是 N 个不同的数字 Pi,表示这 N 个数字的某一排列。1∼N 的某个排列中,代表此中的数字不会相同,故最大值和最小值如果等于数字的个数即必定是连续的;

import java.util.Arrays;
import java.util.Scanner;

public class Main {
   
	static Scanner sc = new Scanner(System.in);
	public static void main(String[] args) {
   
		// TODO Auto-generated method stub
		int n = sc.nextInt();
		int[] a = new int[10005];
		for(int i = 0; i < n; i++) {
   
			a[i] = sc.nextInt();
		}
		int ans = 0;
		
		for(int i = 0; i < n; i++) {
   
			int min = n + 1,max = 0;
			for(int j = i; j < n; j++) {
   
				max = Math.max(max, a[j]);
				min = Math.min(min, a[j]);
				if(j - i == max - min)ans++;
			}
		}
		System.out.println(ans);
	}
}

1236. 递增三元组

给定三个整数数组

A=[A1,A2,…AN],
B=[B1,B2,…BN],
C=[C1,C2,…CN],

请你统计有多少个三元组 (i,j,k) 满足:

1≤i,j,k≤N
Ai<Bj<Ck
输入格式
第一行包含一个整数 N。

第二行包含 N 个整数 A1,A2,…AN。

第三行包含 N 个整数 B1,B2,…BN。

第四行包含 N 个整数 C1,C2,…CN。

输出格式
一个整数表示答案。

数据范围
1≤N≤105,
0≤Ai,Bi,Ci≤105
输入样例:
3
1 1 1
2 2 2
3 3 3
输出样例:
27

import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.Scanner;

public class Main {
   
	static Scanner sc = new Scanner(new BufferedInputStream(System.in));
	static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
	public static void main(String[] args) throws IOException {
   
		int n = sc.nextInt();
		int[] a = new int[100005];int[] b = new int[100005];int[] c = new int[100005];
		int[] cnt = new int[100005];int[] s = new int[100005];
		int[] as = new int[100005];int[] cs = new int[100005];
		
		for(int i = 0; i < n; i++)a[i] = sc.nextInt() + 1;
		for(int i = 0; i < n; i++)b[i] = sc.nextInt() + 1;
		for(int i = 0; i < n; i++)c[i] = sc.nextInt() + 1;
		
		//cnt[i] 代表 值等于 i 的个数,也就是说 cnt里面记录的是 a[i]大小的个数
		for(int i = 0; i < n; i++)cnt[a[i]] ++;
		//s[i]代表 0-i的个数,也就是说 a[i]中小于 i的 个数
		for(int i = 1; i < 100005; i++)s[i] = s[i - 1] + cnt[i];
		
		for(int i = 0; i < n; i++)as[i] = s[b[i]-1];

		Arrays.fill(cnt, 0);Arrays.fill(s, 0);
		//c同理
		for(int i = 0; i < n; i++)cnt[c[i]] ++;
		for(int i = 1; i < 100005; i++)s[i] = s[i - 1] + cnt[i];
		
		
		for(int i = 0; i < n; i++)cs[i] = s[100004] - s[b[i]];
		
		
		long ans = 0;
		//对于每一个b[i] 只需知道比b[i]小的 a[i]有多少个 和 比 b[i]大的 c[i]有多少个相乘,即为答案;
		for(int i = 0; i < n; i++)ans += (long)as[i] * (long)cs[i];
		
		out.write(ans + "\n");
		out.flush();
	}
}

二分:

import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.Scanner;

public class Main {
   
	static Scanner sc = new Scanner(
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值