提醒:篇幅可能有点长,为了方便,大家可以直接看目录快速查找想要的内容
intput:
No
Yes
No
Yes
Yes
output:
No
Yes
No
Yes
Yes
1.要满足一个三带一的话,就是任意选三个数相等且和另一个数不相等一个数不等,有4种情况,这里注意不能4个数都相等,不然都是炸了(斗地主中的炸),那么可以直接写判断,也可以排个序,压缩码量
2.排序后,分两种情况,前三个数相等且和最后一个数不等,或者后三个数相等且和第一个数不等
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
String s;
int T; T= sc.nextInt();
while(T-- >0){
s=sc.next();
char[] a=s.toCharArray(); //转化为字符数组
Arrays.sort(a);
if((a[0]==a[1]&&a[1]==a[2]&&a[2]!=a[3])||(a[3]==a[2]&&a[2]==a[1]&&a[1]!=a[0]))
System.out.println("Yes");
else System.out.println("No");
}
}
}
intput:
3 6
R
L
LL
LR
RL
RR
output:
2
1
1
2
3
4
把二叉树放到一行当中,如下
1
1 2
1 2 3 4
1 2 3 4 5 6 7 8
1.当只有一层时,ans=1,当大于一层时,找找规律(ans为答案)
2.观察左右子树,每向下一层时,遇到L,ans=ans*2-1,遇到R,ans=ans*2
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt(),q=sc.nextInt();
String s;
while(q-->0){
s=sc.next();
int ans=1;
for (int i = 0; i < s.length(); i++) {
if(s.charAt(i)=='L') ans=ans*2-1;
else ans=ans*2;
}
System.out.println(ans);
}
}
}
input:
5 3
8 4 3 6 9
output:
1
1.怎么样才能让极差最小呢?贪心的想应该让身高相差小的分在一组,身高相差小那么有序的话就更好进一步思考,故先排一个序,排序后求极差值直接用最大值-最小值即可。
2.分成k组,那么要求出k个极差,让这k个极差的最大值最小,极差满足二段性,故用二分可以求
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static int k;
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
k=sc.nextInt();
int []a=new int[n];
for(int i=0;i>1;
if(check(a,mid)) r=mid;
else l=mid+1;
}
System.out.println(r-1);
}
//检查极差为mid是否满足条件
private static boolean check(int[] a, int mid) {
int cnt=1; //记录分成几队
for(int l=0,r=0;r=mid){ //注意这里>最后输出r,>=最后输出r-1
l=r; cnt++;
if(cnt>k) return false;
//分的队大于k,返回false,扩大极差l=mid+1
}
}
return true; //cnt小于等于k组 r=mid
}
}
input:
10 3 3
1 4 9
0 3
1 7
2 20
output:
30
1.把空闲的时间区间段拆出来,看成一个小的背包容量
2.对拆出来的每个小背包,跑一个完全背包,累加每一个小背包的最大价值就是答案了
import java.util.Scanner;
public class Main {
static int n,m,q;
static int N=(int)2e5+7;
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
m=sc.nextInt();
q=sc.nextInt();
int[] days=new int[q+2]; //纪录那些天不能去锻炼
for (int i = 1; i <=q; i++) {
days[i]=sc.nextInt();
}
int v[]=new int[m+1];
int w[]=new int[m+1];
for (int i = 1; i <=m; i++) {
int t=sc.nextInt();
v[i]=1<
input:
5
AbbCd
BcDaB
output:
Yes
2
1.两个齿轮都可以旋转,可以只看成一个齿轮可以旋转,让我们直接看s串,因为s是可以旋转的故可以直接拼接复制一倍s串(s+s),方便后续操作,
2.预处理出来与t匹配的串(大小写字母反转),记为target串,在s串中找到target串,找到了输出Yes,否则输出No
3.在s中找target串时,枚举起点记为i,如果匹配成功,注意是可以左右旋转的,可以把前1~i-1个字符移动后面,或者把i+1~n个字符移到前面,对两者取min(i-1,n-i)
4.匹配成功输出Yes并输出最小的旋转次数,否输出No
import java.util.Scanner;
public class Main {
static int base=131;
static int mod=(int)1e9+7;
static int N=(int)2e6+7;
static long[] hash1=new long[N];
static long[] hash2=new long[N];
static long[] p=new long[N];
public static long get1(int l,int r){ //获得s串的hash值
return ((hash1[r]-hash1[l-1]*p[r-l+1])%mod+mod)%mod;
}
public static long get2(int l,int r){ //获得与t匹配的hash值
return ((hash2[r]-hash2[l-1]*p[r-l+1])%mod+mod)%mod;
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
String s=sc.next();
String t=sc.next();
//保证下标从1开始
s=' '+s+s; //可以旋转,复制一倍
t=' '+t;
char cht[]=t.toCharArray(); //t串转化为字符数组
for(int i=1;i<=n;i++){ //将t串大写变小写,小写变大写
if(cht[i]>='A'&&cht[i]<='Z') cht[i]+=32;
else cht[i]-=32;
}
p[0]=1;
for(int i=1;i<=n+n;i++){ //预处理hash值
hash1[i]=(hash1[i-1]*base+s.charAt(i))%mod;
if(i<=n) {
hash2[i]=(hash2[i-1]*base+cht[i])%mod;
p[i]=p[i-1]*base%mod;
}
}
long target=get2(1,n); //获得与t匹配的串
int ans=n;
for(int i=1;i<=n;i++){
if(target==get1(i,i+n-1)) //匹配成功,更新答案
ans=Math.min(ans,Math.min(i-1,n-i+1));
} //将1~i-1个字符后移,或者i~n个字符前移,两者取min
if(ans==n) System.out.println("No");
else{
System.out.println("Yes");
System.out.println(ans);
}
}
}
input:
4 3
1 3
2 5
3 7
4 8
1 5
2 9
5 1
output:
1
2
3
对每个询问直接遍历一遍所有的线段是会tle的(时间复杂度n*q),考虑如何优化呢?这里对a,b分情况讨论
1.对a,b端点的大小分情况讨论,a==b时 答案为0
2.a
3.a>b时,从大到小遍历数轴上的点(此时a为右端点,b为左端点),遇到右端点就将右端点对应的所有左端点处+1,并计算此时左端点在[b+1,a]的个数,即为右端点为a,左端点为b的答案
4.这题用到了,区间查询,单点修改,故直接上树状数组,当然线段树也行,还有注意java要快读,cpp用scanf就行
import java.io.*;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Scanner;
import static java.awt.AWTEventMulticaster.add;
public class Main {
static int N=(int)2e5+7;
static int tr[]=new int[N];
public static void add(int idx,int val){
for(int i=idx;i0;i-=i&-i) res+=tr[i];
return res;
}
//java这题用Scanner会超时,故写了一个快读
public static void main(String[] args) throws IOException {
Scanner sc=new Scanner(System.in);
int n=nextInt(),m=nextInt();
//l[R]:右端点为R对应的的所有左端点
//r[L]:左端点为L对应的所有的右端点
//q[a]:端点a里存的是端点b,与第id个询问
ArrayList[] l=new ArrayList[N];
ArrayList[] r=new ArrayList[N];
ArrayList[] q=new ArrayList[N];
for(int i=0;i();
r[i]=new ArrayList();
q[i]=new ArrayList<>();
}
for(int i=1;i<=n;i++){
int L=nextInt(),R=nextInt();
l[R].add(L);
r[L].add(R);
}
for(int i=0;ia) //左端点为a,右端点为b
ans[p.id]=sum(p.b-1)-sum(a-1);
}
//记得清0
for(int i=0;ib
//枚举右端点a,记录左端点在[b+1,a]中的数量
for(int a=N-1;a>=1;a--){
for(int L:l[a]) add(L,1);
for(Node p:q[a])
if(p.b
双周赛题解将持续更新,希望对你有用!
描述有误,欢迎指正,