第一题:
看到这题,第一感觉就是动规,实际并没有这么复杂通过前缀和即可解决问题。
具体实现通过一个与N大小的数组存储前缀和的mod K 值。然后采用同模相减的方式找出最大子串的长度。
代码如下:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n=sc.nextInt();
int[] s=new int[n];
for(int i=0;i<n;i++){
s[i]=sc.nextInt();
}
int K=sc.nextInt();
int[] sum=new int[n];
for(int j=0;j<n;j++){
for(int i=0;i<=j;i++){
sum[j]+=s[i];
}
sum[j]=sum[j]%K;
}
//low和up用于标记最远两个相同数
int low=0;
int up=0;
//最大子串长度
int max=0;
for(int k=0;k<n-1;k++){
low=k;
for(int j=k+1;j<n;j++){
if(sum[low]==sum[j]&&up<j)
up=j;
}
if(max<up-low) //同模相减
max=up-low;
if(sum[up]==0&&up>max) //%K=0的不需同模相减
max=up+1;
}
System.out.println(max);
sc.close();
}
}
第二题:
开始看到这题茫然不知所措,后来发现下面有个小提示,才得解。
实现思想:相对学生组数按升序排序。然后用最大人数的组作为第一个被抽卷子的,然后顺序遍历每一组,只要每一组都满足该组拿卷子时不会出现卷子数小于0,且不会出现拿到该组卷子的情况,后面就是简单的代码实现。
代码如下:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n=sc.nextInt();
int[] s=new int[n];
for(int i=0;i<n;i++){
s[i]=sc.nextInt();
}
int temp;
//先排个序
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++){
if(s[i]>s[j]){
temp=s[i];
s[i]=s[j];
s[j]=temp;
}
}
temp=s[n-1]; //用于表示桌上的卷子数
int flag=n-1; //当前拿出的卷子的来源组数
int putnum=0; //下一个装入的卷子组数
for(int i=0;i<n;i++){
if(flag==i){ //拿到自己组的卷子
System.out.println("No");
return;
}
temp-=s[i];
if(temp<0){
while(temp<0&&putnum<i){
temp+=s[putnum++];
flag=putnum-1;
}
if(temp<0){ //桌上卷子不够
System.out.println("No");
return;
}
}
}
//所有组都满足条件时即可输出Yes
System.out.println("Yes");
}
}