链接:https://ac.nowcoder.com/acm/contest/11229/C
来源:牛客网
题目描述
牛牛在和它的机器玩猜数字,可是机器好像坏了……
具体来说,机器首先会随机生成一个 1…n的数字 k,紧接着机器会给牛牛 m 条指令,指令的格式有如下三种:
1、op x y;这里,op=1 代表有 x≤k≤y
2、op x;这里, op=2 代表有 x≤k≤n
3、op x;这里, op=3 代表有 1≤k≤x
牛牛知道这台机器已经学会了说谎,所以它所描述的指令可能都是错误的,现在牛牛想知道机器错误的程度以便来制定修理它的方案。
所以牛牛想请你告诉它,当 k 取 1…n 这个范围内的值时,机器最多有多少条指令是错误的,而 k 又有多少种取值方式使得机器的错误指令数最多。
输入描述:
1 2 3 4 5
| 第一行两个整数代表 n,mn,mn,m
接下来 mmm 行每行一条指令,指令格式见题面。 保证: 1≤n≤106; 1≤m≤2×105; 1≤op≤3;
|
输出描述:
1
| 输出共一行两个整数,分别代表机器最多的错误指令数,以及有多少种 k 的取值会使得机器的错误指令数最多。
|
示例1
输入
复制
1 2 3 4 5 6
| 9 5 1 3 6 2 7 1 2 3 3 2 1 5 8
|
输出
复制
说明
1 2 3 4 5
| 最多的错误指令数为 4。 使得错误指令数最多的取值有 3 种,分别是: 取值为 1,此时第 1、2、3、5 条指令是错误的。 取值为 4,此时第 2、3、4、5 条指令是错误的。 取值为 9,此时第 1、3、4、5 条指令是错误的。
|
笔者解析
本题是小白月赛中的第三题,使用一维差分数组来计算相关所需数据。
若要是的计算范围为错误的,则要避开正确答案
1 2 3
| p1 则错误的情况为1<= k < x && y < k <=n p2 则表示1<=k<x &&n<k,但是题目已经告知k在1~n范围内 p3 则表示x<k<=n
|
笔者代码
java版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;
public class Main { public static int N = 1000010;
public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); String[] str = reader.readLine().split(" "); int n = Integer.parseInt(str[0]); int m = Integer.parseInt(str[1]); int[] a = new int[N]; int x,y; while(m-->0){ str = reader.readLine().split(" "); if(str[0].equals("1")){ x = Integer.parseInt(str[1]); y = Integer.parseInt(str[2]); a[1]++;a[x]--; a[y+1]++;a[n+1]--; }else if(str[0].equals("2")){ x = Integer.parseInt(str[1]); a[1]++;a[x]--; }else { x = Integer.parseInt(str[1]); a[x+1]++;a[n+1]--; } } for(int i = 1;i<=n;i++){ a[i] += a[i-1]; } int max = -1,all = 0; for(int i = 1;i<=n;i++){ max=Math.max(max, a[i]); } for(int i = 1;i<=n;i++){ if(a[i]==max){all++;} } System.out.println(max+" "+all); }
}
|
C++版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| #include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 1e6+10; int a[N]; int n,m; int main() { scanf("%d%d", &n, &m); while (m -- ) { int op,x,y; cin>>op>>x; if(op==1) { cin>>y; a[1]++,a[x]--; a[y+1]++,a[n+1]--; } else if(op==2) { a[1]++,a[x]--; } else { a[x+1]++,a[n+1]--; } } for(int i=1;i<=n;i++) a[i]+=a[i-1]; int maxn=0,res=0; for(int i=1;i<=n;i++) { maxn=max(maxn,a[i]); } for(int i=1;i<=n;i++) if(a[i]==maxn) res++; cout<<maxn<<' '<<res<<endl; return 0; }
|