过年了,最近甚为咸鱼,赶紧来练练代码,顺便练练用Java写算法(写的好慢。。)
- https://ac.nowcoder.com/acm/contest/370/C
签到题,只需要记录每行,每列最新的记录,然后对于一个点(x,y)求x行和y列刷新的最大值即可,复杂度O(mn)
import java.util.Scanner;
public class Main{
static private long mod = 1000000007;
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
int n = cin.nextInt(), m = cin.nextInt(), T = cin.nextInt();
int [][] arr = new int[3][Math.max(n, m)+5];
for(int i=1; i<=T; i++){
arr[cin.nextInt()][cin.nextInt()] = i;
}
for(int i=1; i<=n; i++){
for(int j=1; j<=m; j++){
System.out.print(Math.max(arr[1][i], arr[2][j]) + " ");
}
System.out.println();
}
}
}
- https://ac.nowcoder.com/acm/contest/370/J
最简化根式,暴力抽出所有平方因子就可以,复杂度O(T√n)
import java.util.Scanner;
public class Main{
static private long mod = 1000000007;
static private int [] arr = new int[1000];
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
int T = cin.nextInt();
for(int i=1; i<=T; i++){
int a = cin.nextInt();
if(a < 0){
System.out.println(-1);
}else {
int sqr = ((int) Math.sqrt(a)), ans = 1;
for(int j = sqr; j>0; j--){
if(a % (j*j) == 0){
ans *= j;
a /= (j*j);
}
}
System.out.println(ans + " " + a);
}
}
}
}
- https://ac.nowcoder.com/acm/contest/370/F
树形dp,M = N-1,所以是树。假设v是u的其中一个孩子,w为权重,递推式:dp[u] += min(dp[u], w)。注意dfs的时候,要把父亲删掉,
import java.util.*;
public class Main{
static private final int mod = 1000000007, max = 100005;
static private long [] dp = new long[max];
private static Map<Integer, List<Edge>> g = new HashMap<>();
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
int n = cin.nextInt(), m = cin.nextInt(), s = cin.nextInt();
//邻接矩阵存不下,采用邻接表
for(int i=0; i<m; i++){
int from = cin.nextInt(), to = cin.nextInt(), w = cin.nextInt();
add(from, to, w);
add(to, from, w);
}
//树形dp
dfs(s, 0);
System.out.println(dp[s]);
}
private static class Edge{
int from, to, w;
public Edge(int from, int to, int w) {
this.from = from;
this.to = to;
this.w = w;
}
}
private static void add(int from, int to, int w){
if(g.containsKey(from)){
g.get(from).add(new Edge(from, to, w));
}else {
List<Edge> list = new ArrayList<>();
list.add(new Edge(from, to, w));
g.put(from, list);
}
}
private static void dfs(int root, int f){
for(Edge e : g.get(root)){
if(e.to == f){//碰到的是父亲
continue;
}
dfs(e.to, root);
dp[root] += Math.min(dp[e.to], e.w);
}
if(dp[root] == 0){
dp[root] = Long.MAX_VALUE;
}
}
}
- https://ac.nowcoder.com/acm/contest/370/I
首先要对递推式进行合并,可以得到
然后根据异或运算的特性,1只对0有贡献,0只对1有贡献。拆位,一位一位来看,从二进制的角度进行运算,设从A0 - Ai的第j位共有wA[j][0]个0,wA[j][1]个1,wB同理。可得C的第j位是wA[j][0]*wB[j][1] + wA[j][1]*wB[j][0],然后转为十进制即可。注意数据溢出。
import java.util.Scanner;
public class Main{
static private final int mod = 1000000007, max = 100005;
static private long [][] wA = new long[40][2], wB = new long[40][2];
static private int [] A = new int[max], B = new int[max];
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
int n = cin.nextInt();
for(int i=1; i<=n; i++){
A[i] = cin.nextInt();
}
for(int i=1; i<=n; i++){
B[i] = cin.nextInt();
}
for(int i=1; i<=n; i++){
long c = 0;
for(int j=0; j<=30; j++){
//统计第ai对于第j位的贡献
wA[j][(A[i]>>j)&1]++;
wB[j][(B[i]>>j)&1]++;
c = (c + (1<<j) * (wA[j][0]*wB[j][1] + wA[j][1]*wB[j][0]))%mod;
}
System.out.print(c + " ");
}
System.out.println();
}
}