没有那么多天赋异禀
优秀的人总是在努力翻山越岭
你所看到的惊艳,都曾被平庸历练
接受自己的普通,然后拼尽全力的去与众不同
成为你想成为的人,什么时候都不晚
追赶日月,不苟于山川
目录
A:找素数(欧拉筛)
一个欧拉筛模板就可以了,不会欧拉筛的朋友可以看看这篇我个人觉得好理解的:欧拉筛
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int []arr=new int[100003];//存放质数
boolean []brr=new boolean[10000000];
brr[0]=brr[1]=true;//0和1都不为质数
int t=0;
for (int i=2;i<10000000 ;i++ ){
if (!brr[i]){//为质数
arr[t]=i;//加入质数列表
t++;
if(t==100002){
System.out.println(arr[t-1]);
return;
}
}
for(int j=0;j<t&&i*arr[j]<10000000;j++){//标记非质数
brr[arr[j]*i]=true;
if(i%arr[j]==0) break;//避免重复
}
}
}
}
B:图书排列(bfs模板)
第一眼感觉是dp,如果把数据变大的话可以当成dp做,但是因为只有10本,所以可以直接进行全排列,所以直接bfs模板用上就行
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
static int []arr={1,2,3,4,5,6,7,8,9,10};
static int count=0;
public static void main(String[] args) {
dfs(0);
System.out.println(count);
}
public static void dfs(int step){
if(step==10){
pd();
return;
}
for (int i=step;i<arr.length;i++){
swap(i,step);
dfs(step+1);
swap(i,step);
}
}
public static void swap(int i,int j)
{
int t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
public static void pd(){
for(int i=0;i<=8;i++){
if(Math.abs(arr[i]-arr[i+1])==1) return;
}
count++;
}
}
C:日志统计(双指针)
这题的思路挺清晰的,因为结果也是需要按照编号从小到大输出,那我们排序的时候就先将编号从小到大排序,编号相同的情况下时间小的在前面
通过双指针去判断 arr[L][1]是否等于arr[R][1],并且arr[R][0]-arr[L][0]<d,R-L+1>=k,即可表示该编号是一个热帖,当左右端点编号不同时,我们把左端点变成右端点,当左右端点时间差值>=D时,我们将左端点右移,用于维护长度为R-L的区间即可
import java.util.Arrays;
import java.io.*;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer st = new StreamTokenizer(br);
static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws Exception {
int n = nextInt();//数据个数n
int d = nextInt();//时间间隔d
int k = nextInt();//达标个数k
int[][] arr = new int[n][2];
for (int i = 0; i < n; i++) {
arr[i][0] = nextInt();
arr[i][1] = nextInt();
}
Arrays.sort(arr,((a,b)->{//按照编号优先进行排序
if (a[1]!=b[1]){
return a[1]-b[1];
}
return a[0]-b[0];
}));
int t=0,s=0;
int []brr=new int[n];//用于存放满足的编号
int l=0;//左端点
for(int r=0;r<n;r++){//右端点
if(arr[r][1]!=arr[l][1]){//左右端点编号不同
if(t==1){//说明是热帖
brr[s++]=arr[l][1];//存入
}
t=0;
l=r;//左端点更改为右端点
}
if(arr[r][0]-arr[l][0]>=d) l++;//左端点右移
if(r-l>=k-1) t=1;//标记该编号为热点
}
if(t==1) brr[s++]=arr[n-1][1];//最后一个编号的判断
for(int i=0;i<s;i++) pw.println(brr[i]);//输出
pw.flush();
}
public static int nextInt() throws Exception {//int型
st.nextToken();
return (int) st.nval;
}
public static long nextLong() throws Exception {//long型
st.nextToken();
return (long) st.nval;
}
}
D:杨辉三角(思维找规律)
杨辉三角,老朋友了,个人觉得这是一个比较考验思维的题吧
对于这题我们需要将二维转化为一维
在第x行时,arr[x-1][x-1]=arr[x][x]=1;arr[x-1][x]=0;
arr[x][x]=arr[x-1][x-1]+arr[x-1][x]>>arr[x][x]+=arr[x-1][x]
那么换成一维的情况就是:arr[x]+=arr[x-1];
通过杨辉三角的对称性质,我们可以进行砍办,同时因为n<=1e9;在第33行时出现第一个大于1e9的数字,所以实际我们每一行只需要判断最多16个数
当(1+n)*n/2>=1e9时,n=44721;所以定义一维数组长度超过44721即可
还不能理解的话可以看看这篇(废话比较多的讲解)
import java.util.Arrays;
import java.io.*;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer st = new StreamTokenizer(br);
static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws Exception {
long n=nextLong();
int []arr=new int[44725];
arr[0]=1;
long k=1L;
if(n==1){
pw.println(1);
pw.flush();
return;
}
for(int i=1;i<44725;i++){
for(int j=i;j>=i-16&&j>=1;j--){
arr[j]+=arr[j-1];
if(arr[j]==n){
pw.println(k+i-j+1);
pw.flush();
return;
}
}
k+=i+1;
}
pw.println((n*(n+1)/2)+2);
pw.flush();
}
public static int nextInt() throws Exception {//int型
st.nextToken();
return (int) st.nval;
}
public static long nextLong() throws Exception {//long型
st.nextToken();
return (long) st.nval;
}
}