给两个数组,一个长度为
,一个长度为
,其中
。
现从中任意取出元素构成长度为
的数组
,问
最大能为多少。
定义分别表示第i次选
的头(0)或尾(1)后,得到最大值时,新的
序列,
序列和最大值。
同理
可以先用进行更新,若
得到的结果小,则不用更新,直接
没有很复杂吧,代码重复性挺高的,很好写
import java.io.*;
import java.util.Arrays;
import java.util.Scanner;
public class Main{
public static void main(String[] args) throws IOException{
Scanner input=new Scanner(System.in);
int T=input.nextInt();
while(true) {
if(T==0)break;
int n=input.nextInt();
int m=input.nextInt();
long[] a=new long[n];
long[] b=new long[m];
for(int i=0;if[i][0].ans) {
al++;br--;
f[i][0]=new Node(al,ar,bl,br);
f[i][0].ans=f[i-1][1].ans+flr;
al--;br++;
}
}else {
long ft=f[i-1][1].ans+fll;
if(ft>f[i][0].ans) {
al++;bl++;
f[i][0]=new Node(al,ar,bl,br);
f[i][0].ans=f[i-1][1].ans+fll;
al--;bl--;
}
}
if(frl<=frr) {
long ft=f[i-1][1].ans+frr;
if(ft>f[i][1].ans) {
ar--;br--;
f[i][1]=new Node(al,ar,bl,br);
f[i][1].ans=f[i-1][1].ans+frr;
ar++;br++;
}
}else {
long ft=f[i-1][1].ans+frl;
if(ft>f[i][1].ans) {
ar--;bl++;
f[i][1]=new Node(al,ar,bl,br);
f[i][1].ans=f[i-1][1].ans+frl;
ar++;bl--;
}
}
}
System.out.println(Math.max(f[n-1][0].ans,f[n-1][1].ans));
T--;
}
}
}
class Node{
int al;
int ar;
int bl;
int br;
long ans;
public Node(int aL,int aR,int bL,int bR) {
al=aL;
ar=aR;
bl=bL;
br=bR;
}
}
在一个棋盘内,有两个不同的点,
只能往左下,下,右下走,
只能往左上,上,右上走。
先走,
后走,问最终是
吃
,还是
吃
,或者不相遇为平局。双方都不傻。
import java.io.*;
import java.util.Scanner;
public class Main{
public static void main(String[] args) throws IOException{
Scanner input=new Scanner(System.in);
int T=input.nextInt();
while(true) {
if(T==0) break;
int h=input.nextInt();
int w=input.nextInt();
int a=input.nextInt();
int b=input.nextInt();
int c=input.nextInt();
int d=input.nextInt();
//A在B下面或同一行
if(a>=c) {
System.out.println("Draw");
T--;
continue;
}
int x=c-a;
if(x%2!=0) {
//则A/D
//A上来直接吃
if(Math.abs(b-d)<=1) {
System.out.println("Alice");
T--;
continue;
}
//Alice跑到边界追上Bob的步数
int may=b
给一个长度为的数组,有
次询问。查询
例:
已知,要查询
的序列,则
import java.io.*;
import java.util.Scanner;
import java.util.StringTokenizer;
public class Main{
public static void main(String[] args) throws IOException{
AReader input=new AReader();
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
int T=input.nextInt();
while(true) {
if(T==0) break;
int n=input.nextInt();
int q=input.nextInt();
int w=(int)Math.sqrt(n);
long[] a=new long[n+1];
long[][] f=new long[w+1][n+1];
long[][] g=new long[w+1][n+1];
for(int i=1;i<=n;++i)a[i]=input.nextLong();
//预处理
for(int i=1;i<=w;++i) {
for(int t=0;tw) {//暴力
int t=s;
for(int i=1;i<=k;++i) {
ans+=a[t]*i;
t=t+d;
}
}else {
if(d>s) {//s-d<0
ans=f[d][s+d*(k-1)];
}else {
ans=(f[d][s+d*(k-1)]-f[d][s-d])-(g[d][s+d*(k-1)]-g[d][s-d])*(s/d);
}
}
out.print(ans+" ");
q--;
}
out.println();
T--;
}
out.flush();
out.close();
}
static
class AReader {
private BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
private StringTokenizer tokenizer = new StringTokenizer("");
private String innerNextLine() {
try {
return reader.readLine();
} catch (IOException ex) {
return null;
}
}
public boolean hasNext() {
while (!tokenizer.hasMoreTokens()) {
String nextLine = innerNextLine();
if (nextLine == null) {
return false;
}
tokenizer = new StringTokenizer(nextLine);
}
return true;
}
public String nextLine() {
tokenizer = new StringTokenizer("");
return innerNextLine();
}
public String next() {
hasNext();
return tokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
}
}
给一个图,图上有一些特殊点。在图上任选一点,从这个点开始向左上,右上,左下,右下,用边长为的三角形进行覆盖,问能覆盖到的最大特殊点数。
import java.io.*;
import java.util.Scanner;
import java.util.StringTokenizer;
public class Main{
public static void main(String[] args) throws IOException{
AReader input=new AReader();
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
int T=input.nextInt();
while(true) {
if(T==0) break;
int n=input.nextInt();
int m=input.nextInt();
int k=input.nextInt();
char[][] map=new char[n+1][m+1];//n*m<=1e5
for(int i=1;i<=n;++i) {
String s=" "+input.next();
map[i]=s.toCharArray();
}
int ans=0;
for(int turn=1;turn<=4;++turn) {
int[][] sum=new int[n+1][m+1];
int[][] b=new int[n+1][m+1];//斜线
//前缀和
for(int i=1;i<=n;++i) {
for(int j=1;j<=m;++j) {
if(map[i][j]=='#') {
sum[i][j]++;
b[i][j]++;
}
sum[i][j]+=sum[i][j-1]+sum[i-1][j]-sum[i-1][j-1];
b[i][j]+=b[i-1][j-1];
}
}
for(int i=1;i<=n;++i) {
int now=0;
for(int j=1;j<=m;++j) {
int di=Math.min(n,i+k);//右下坐标的i
//加一列
now+=sum[di][j]-sum[i-1][j]-sum[di][j-1]+sum[i-1][j-1];
//处理斜线
if(j-1<1) {//移动之前三角形还没有覆盖
ans=Math.max(ans, now);
continue;
}
int zuoshangj=Math.max(1, j-k-1);
//超出边界时,取边界(或边界的延长线)与三角形的交点为左上
int zuoshangi=zuoshangj-(j-1-k)+i;
//左上坐标的i
int youxiaj=j-1-Math.max(i+k-n, 0);
//右下坐标的j
if(youxiaj<1||zuoshangi>n) {
//边界与三角形的交点在图像范围之外,即斜线与图没有重叠
ans=Math.max(ans, now);
continue;
}
now-=b[di][youxiaj]-b[zuoshangi-1][zuoshangj-1];
ans=Math.max(ans, now);
}
}
int t=n;
n=m;
m=t;
//顺时针旋转
char[][] map2=new char[n+1][m+1];
for(int i=1;i<=n;++i) {
for(int j=1;j<=m;++j) {
map2[i][j]=map[m-j+1][i];
}
}
map=map2;
}
System.out.println(ans);
T--;
}
out.flush();
out.close();
}
static
class AReader {
private BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
private StringTokenizer tokenizer = new StringTokenizer("");
private String innerNextLine() {
try {
return reader.readLine();
} catch (IOException ex) {
return null;
}
}
public boolean hasNext() {
while (!tokenizer.hasMoreTokens()) {
String nextLine = innerNextLine();
if (nextLine == null) {
return false;
}
tokenizer = new StringTokenizer(nextLine);
}
return true;
}
public String nextLine() {
tokenizer = new StringTokenizer("");
return innerNextLine();
}
public String next() {
hasNext();
return tokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
}
}