• JAVA蓝桥国赛备战


    2019.5.16

    二分:POJ - 3258

    有一堆牛要过河,河的长度是l,河中间有n个石头,牛只能踩着石头过河,问去掉m个石头后(去掉这m个石头的方式是随机的)的每种情况牛能走的石头间距最小值中,最大的那一个是多少

    输入:25 5 2//河的长度,一共有几块石头,去掉m块

              2 14 11 21 17//这n块石头的位置

    输出:4

    思路:二分距离 check函数注意写法

     1 import java.util.Arrays;
     2 import java.util.Scanner;
     3 
     4 public class Main {
     5     static int n,m;
     6     static int len;
     7     static int [] b = new int [50010];
     8     static boolean check(int x) {
     9         int cnt = 0;
    10         int pos = 0;
    11         
    12         for(int i=1;i<=n+1;i++) {
    13             
    14             if(b[i]-b[pos]<x) {
    15                 
    16                 cnt++;
    17                 if(cnt>m)
    18                     return false;
    19             }
    20             else
    21                 pos = i;
    22         }
    23         return true;
    24     }
    25     public static void main(String[] args) {
    26         Scanner cin = new Scanner(System.in);
    27         len = cin.nextInt();
    28         n = cin.nextInt();
    29         m = cin.nextInt();
    30         for(int i=1;i<=n;i++)
    31             b[i] = cin.nextInt();
    32         b[0] = 0;
    33         b[n+1] = len;
    34         Arrays.sort(b, 0, n+2);
    35         
    36         int l = 0, r = len;
    37         int ans = 0;
    38         while(l<=r) {
    39             int mid = (l+r)/2;
    40             if(check(mid)) {
    41                 l = mid + 1;
    42                 ans = mid;
    43             }
    44             else
    45                 r = mid - 1;
    46         }
    47         System.out.println(ans);
    48     }
    49 }

     2019.5.17

      昨天肚子疼,没怎么干活 今天补上。

    dijkstra 用我自己写的怎么写怎么RE,改成了某大神的:

    5个顶点1~5,5条双向边。求从1到n的最短路
    5 5 1 2 20 2 3 30 3 4 20 4 5 20 1 5 100
    输出 90
     1 import java.util.Arrays;
     2 import java.util.PriorityQueue;
     3 import java.util.Scanner;
     4 
     5 class node implements Comparable<node>{
     6     int to;
     7     int w;
     8     int next;
     9     public node(int to,int w,int next) {
    10         this.to= to;
    11         this.w = w;
    12         this.next = next;
    13         // TODO Auto-generated constructor stub
    14     }
    15     @Override
    16     public int compareTo(node x) {
    17         // TODO Auto-generated method stub
    18         return this.w-x.w;
    19     }
    20 }
    21 public class Main {
    22     static final int inf = 0x3f3f3f3f;
    23     static int m,n,cnt;
    24     static node [] e;
    25     static int [] vis,dis,head;
    26     static PriorityQueue<node> q = new PriorityQueue<node>();
    27     static void init() {
    28         e = new node[2*m];
    29         head = new int [n+10];
    30         vis = new int [n+10];
    31         dis = new int [n+10];
    32         Arrays.fill(dis, inf);
    33         Arrays.fill(head, -1);
    34         cnt = 0;
    35     }
    36     static void add(int x,int y,int w) {
    37         e[cnt] = new node(y, w, head[x]);
    38         head[x] = cnt++;
    39     }
    40     static void dijkstra(int st) {
    41         dis[st] = 0;
    42         q.offer(new node(st, 0, 0));
    43         while(!q.isEmpty()) {
    44             int pos = q.poll().to;
    45             if(vis[pos]==1)
    46                 continue;
    47             vis[pos] = 1;
    48             for(int i=head[pos];i!=-1;i=e[i].next) {
    49                 int to = e[i].to;
    50                 if(dis[to]>dis[pos]+e[i].w) {
    51                     dis[to] = dis[pos] + e[i].w;
    52                     q.offer(new node(to, dis[to], 0));
    53                 }
    54             }
    55         }
    56         System.out.println(dis[n]);
    57     }
    58     public static void main(String[] args) {
    59         Scanner cin = new Scanner(System.in);
    60         m = cin.nextInt();
    61         n = cin.nextInt();
    62         init();
    63         int a,b,c;
    64         for(int i=0;i<m;i++) {
    65             a = cin.nextInt();
    66             b = cin.nextInt();
    67             c = cin.nextInt();
    68             add(a, b, c);
    69             add(b, a, c);
    70         }
    71         dijkstra(1);
    72     }
    73 }

     5.19

    tarjan强连通:

    题目描述

    在幻想乡,上白泽慧音是以知识渊博闻名的老师。春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄。因此慧音决定换一个能够聚集最多人数的村庄作为新的教学地点。人间之里由N个村庄(编号为1..N)和M条道路组成,道路分为两种一种为单向通行的,一种为双向通行的,分别用1和2来标记。如果存在由村庄A到达村庄B的通路,那么我们认为可以从村庄A到达村庄B,记为(A,B)。当(A,B)和(B,A)同时满足时,我们认为A,B是绝对连通的,记为<A,B>。绝对连通区域是指一个村庄的集合,在这个集合中任意两个村庄X,Y都满足<X,Y>。现在你的任务是,找出最大的绝对连通区域,并将这个绝对连通区域的村庄按编号依次输出。若存在两个最大的,输出字典序最小的,比如当存在1,3,4和2,5,6这两个最大连通区域时,输出的是1,3,4。

    输入输出格式

    输入格式:

    第1行:两个正整数N,M

    第2..M+1行:每行三个正整数a,b,t, t = 1表示存在从村庄a到b的单向道路,t = 2表示村庄a,b之间存在双向通行的道路。保证每条道路只出现一次。

    输出格式:

    第1行: 1个整数,表示最大的绝对连通区域包含的村庄个数。

    第2行:若干个整数,依次输出最大的绝对连通区域所包含的村庄编号。

    输入输出样例

    输入样例#1: 复制
    5 5
    1 2 1
    1 3 2
    2 4 2
    5 1 2
    3 5 1
    
    输出样例#1: 复制
    3
    1 3 5
    

    说明

    对于60%的数据:N <= 200且M <= 10,000

    对于100%的数据:N <= 5,000且M <= 50,000

     1 import java.util.ArrayList;
     2 import java.util.Scanner;
     3 
     4 public class Main {
     5     static int n,m;
     6     static int [] dfn,sta,vis,low;
     7     static int top=-1,sum,cnt;
     8     static ArrayList<Integer> v[]  = new ArrayList[50010] ;
     9     static void tarjan(int u) {
    10         dfn[u] = low[u] = cnt++;
    11         sta[++top] = u;
    12         vis[u] = 1;
    13         for(int i=0;i<v[u].size();i++) {
    14             int to = v[u].get(i);
    15             if(dfn[to]==0) {
    16                 tarjan(to);
    17                 low[u] = Math.min(low[u], low[to]);
    18             }
    19             else {
    20                 if(vis[to]==1) {
    21                     low[u] = Math.min(low[u], low[to]);
    22                 }
    23             }
    24             
    25         }
    26         if(dfn[u]==low[u]) {
    27             int num = 0;
    28             while(sta[top]!=u) {
    29                 num++;
    30                 vis[sta[top--]] = 0;
    31             }
    32             vis[sta[top--]] = 0;
    33             num++;
    34             if(num>1)
    35                 sum++;
    36         }
    37     }
    38     public static void main(String[] args) {
    39         Scanner cin = new Scanner(System.in);
    40         n = cin.nextInt();
    41         m = cin.nextInt();
    42         dfn = new int [n+10];
    43         sta = new int [n+10];
    44         vis = new int [n+10];
    45         low = new int [n+10];
    46         
    47         for(int i=0;i<50010;i++) {
    48             v[i] = new ArrayList<Integer>();
    49         }
    50         for(int i=0;i<m;i++) {
    51             int x = cin.nextInt();
    52             int y = cin.nextInt();
    53             v[x].add(y);
    54         }
    55         for(int i=1;i<=n;i++) {
    56             if(dfn[i]==0)
    57                 tarjan(i);
    58         }
    59         System.out.println(sum);
    60     }
    61 }

    有color版:

     1 import java.util.ArrayList;
     2 import java.util.Scanner;
     3 
     4 public class Main {
     5     static int n,m;
     6     static int top = -1,cnt,sum,ans,ansc;
     7     static int [] dfn,vis,sta,low,color;
     8     static ArrayList<Integer> v[] = new ArrayList[5010];
     9     static void tarjan(int u) {
    10         dfn[u] = low[u] = cnt++;
    11         vis[u] = 1;
    12         sta[++top] = u;
    13         for(int i=0;i<v[u].size();i++) {
    14             int to = v[u].get(i);
    15             if(dfn[to]==0) {
    16                 tarjan(to);
    17                 low[u] = Math.min(low[u], low[to]);
    18             }
    19             else {
    20                 if(vis[to]==1) {
    21                     low[u] = Math.min(low[u], low[to]);
    22                 }
    23             }
    24         }
    25         if(dfn[u]==low[u]) {
    26             int num = 0;
    27             color[u] = ++sum;
    28             while(sta[top]!=u) {
    29                 num++;
    30                 color[sta[top]] = sum;
    31                 vis[sta[top--]] = 0;
    32             }
    33             vis[sta[top--]] = 0;
    34             num++;
    35             if(num>ans) {
    36                 ans = num;
    37                 ansc = sum;
    38             }
    39         }
    40     }
    41     public static void main(String[] args) {
    42         Scanner cin = new Scanner(System.in);
    43         n = cin.nextInt();
    44         m = cin.nextInt();
    45         for(int i=0;i<n+10;i++)
    46             v[i] = new ArrayList<>();
    47         dfn = new int [n+10];
    48         vis = new int [n+10];
    49         sta = new int [n+10];
    50         low = new int [n+10];
    51         color = new int [n+10];
    52         for(int i=1;i<=m;i++) {
    53             int x,y,op;
    54             x = cin.nextInt();
    55             y = cin.nextInt();
    56             op = cin.nextInt();
    57             if(op==1) {
    58                 v[x].add(y);
    59             }else {
    60                 v[x].add(y);
    61                 v[y].add(x);
    62             }
    63         }
    64         for(int i=1;i<=n;i++) {
    65             if(dfn[i]==0) {
    66                 tarjan(i);
    67             }
    68         }
    69         System.out.println(ans);
    70         for(int i=1;i<=n;i++) {
    71             if(color[i]==ansc) {
    72                 System.out.print(i+" ");
    73             }
    74         }
    75     }
    76 }

    dfs

    速算24点

     1 import java.util.Arrays;
     2 import java.util.Scanner;
     3 
     4 public class Main {
     5     static int [] num = new int [5];
     6     static int [] a = new int [5];
     7     static int [] vis = new int [5];
     8     static int flag;
     9     static void check(int sum,int cur,int step) {
    10         if(flag==1)
    11             return;
    12         if(step==3) {
    13             if(sum+cur==24||sum-cur==24||sum*cur==24)
    14                 flag = 1;
    15             if(cur!=0&&sum%cur==0)
    16                 if(sum/cur==24)
    17                     flag = 1;
    18             return;
    19         }
    20         check(sum+cur, num[step+1], step+1);
    21         check(sum-cur, num[step+1], step+1);
    22         check(sum*cur, num[step+1], step+1);
    23         if(cur!=0&&sum%cur==0)
    24             check(sum/cur, num[step+1], step+1);
    25         check(sum, cur+num[step+1], step+1);
    26         check(sum, cur-num[step+1], step+1);
    27         check(sum, cur*num[step+1], step+1);
    28         if(num[step+1]!=0&&cur%num[step+1]==0)
    29             check(sum, cur/num[step+1], step+1);
    30     }
    31     static void dfs(int step) {
    32         if(step==4) {
    33             check(num[0],num[1],1);
    34             return;
    35         }
    36         for(int i=0;i<4;i++) {
    37             if(vis[i]==0) {
    38                 vis[i] = 1;
    39                 num[step] = a[i];
    40                 dfs(step+1);
    41                 vis[i] = 0;
    42             }
    43         }
    44     }
    45     public static void main(String[] args) {
    46         Scanner cin = new Scanner(System.in);
    47         while(cin.hasNext()) {
    48             flag = 0;
    49             String ss = cin.nextLine();
    50             String [] s = ss.split(" ");
    51             for(int i=0;i<4;i++) {
    52                 if(s[i].compareTo("0")>=0&&s[i].compareTo("9")<=0)
    53                     a[i] = Integer.parseInt(s[i]);
    54                 else if(s[i].equals("A"))
    55                     a[i] = 1;
    56                 else if(s[i].equals("10"))
    57                     a[i] = 10;
    58                 else if(s[i].equals("J"))
    59                     a[i] = 11;
    60                 else if(s[i].equals("Q"))
    61                     a[i] = 12;
    62                 else if(s[i].equals("K"))
    63                     a[i] = 13;
    64             }
    65             Arrays.sort(a, 0,4);
    66             for(int i=0;i<5;i++)
    67                 vis[i] = 0;
    68             dfs(0);
    69             if(flag==1)
    70                 System.out.println("Yes");
    71             else
    72                 System.out.println("No");
    73         }    
    74     }
    75 }

    单调栈:

    题意:给你一个非负整数数组,定义某个区间的参考值为:区间所有元素的和乘以区间最小元素。求该数组中的最大参考值以及对应的区间。
    比如说有6个数3 1 6 4 5 2
    最大参考值为6,4,5组成的区间,区间最小值为4,参考值为4*(6+5+4)=60
    数据范围1<=n<=100000;

     1 import java.util.Scanner;
     2 import java.util.Stack;
     3 
     4 public class Main{
     5     static int n;
     6     static int [] l,r;
     7     static long [] a,sum;
     8     public static void main(String[] args) {
     9         Scanner cin = new Scanner(System.in);
    10         n = cin.nextInt();
    11         a = new long [n+10];
    12         l = new int [n+10];
    13         r = new int [n+10];
    14         sum = new long [n+10];
    15         for(int i=1;i<=n;i++) {
    16             a[i] = cin.nextLong();
    17             sum[i] = sum[i-1]+a[i];
    18         }
    19         Stack<Integer>s = new Stack<Integer>();
    20         for(int i=1;i<=n;i++) {
    21             while(!s.isEmpty()&&a[s.peek()]>=a[i])
    22                 s.pop();
    23             if(s.isEmpty())
    24                 l[i] = 0;
    25             else
    26                 l[i] = s.peek();
    27             s.push(i);
    28         }
    29         while(!s.isEmpty())
    30             s.pop();
    31         for(int i=n;i>=1;i--) {
    32             while(!s.isEmpty()&&a[s.peek()]>=a[i])
    33                 s.pop();
    34             if(s.isEmpty())
    35                 r[i] = n+1;
    36             else
    37                 r[i] = s.peek();
    38             s.push(i);
    39         }
    40         int posl = 0,posr = 0;
    41         long ans = -1;
    42         for(int i=1;i<=n;i++) {
    43             //System.out.println("i="+i+" "+l[i]+" "+r[i]);
    44             long tmp = a[i]*(sum[r[i]-1]-sum[l[i]]);
    45             //System.out.println(tmp);
    46             if(tmp>ans) {
    47                 ans = tmp;
    48                 posl = l[i] + 1;
    49                 posr = r[i] - 1;
    50             }
    51         }
    52         System.out.println(ans);
    53         System.out.println(posl+" "+posr);
    54     }
    55 }

     5.20 今天是520鸭!!

    简单尺取:

    N个数,找到区间和大于等于m的最小区间长度,没有输出0。

    2
    10 15
    5 1 3 5 10 7 4 9 2 8
    输出 2 5 11 1 2 3 4 5
    输出 3
     1 import java.util.Scanner;
     2 
     3 public class Main {
     4     static int casen,n;
     5     static long m;
     6     static long [] a,sum;
     7     public static void main(String[] args) {
     8         Scanner cin = new Scanner(System.in);
     9         casen = cin.nextInt();
    10         while(casen-->0) {
    11             n = cin.nextInt();
    12             m = cin.nextLong();
    13             a = new long [n+10];
    14             sum = new long [n+10];
    15             for(int i=1;i<=n;i++) {
    16                 a[i] = cin.nextLong();
    17                 sum[i] = sum[i-1] + a[i];
    18             }
    19             int l = 1;
    20             int r = 1;
    21             int flag = 0;
    22             int ans = 0x3f3f3f3f;
    23             while(r<=n) {
    24                 while(r<=n&&sum[r]-sum[l-1]<m) {
    25                     r++;
    26                 }
    27                 if(sum[r]-sum[l-1]>=m) {
    28                     flag = 1;
    29                     ans = Math.min(ans, r-l+1);
    30                 }
    31                 l++;
    32             }
    33             if(flag==1)
    34                 System.out.println(ans);
    35             else
    36                 System.out.println(0);
    37         }
    38     }
    39 }

     二分图匹配:

    一共有N个学生跟P门课程,一个学生可以任意选一 门或多门课,问是否达成: 
      1.每个学生选的都是不同的课(即不能有两个学生选同一门课)
      2.每门课都有一个代表(即P门课都被成功选过)
    输入为:
    第一行一个T代表T组数据
    P N(P课程数, N学生数)
    接着P行:
    第几行代表第几门课程,首先是一个数字k代表对这门课程感兴趣的同学的个数,接下来是k个对这门课程感兴趣同学的编号。
    输出为:
    若能满足上面两个要求这输出”YES”,否则为”NO”
    注意:是课程匹配的学生,学生没课上没事.....
    Input
    2
    3 3
    3 1 2 3
    2 1 2
    1 1
    3 3
    2 1 3
    2 1 3
    1 1
    Output
    YES
    NO 
     1 import java.util.Arrays;
     2 import java.util.Scanner;
     3 
     4 public class Main {
     5     static int n,p,k,casen;
     6     static int [][] link;
     7     static int [] match,used;
     8     static boolean find(int x) {
     9         for(int i=1;i<=n;i++) {
    10             if(link[x][i]==1&&used[i]==0) {
    11                 used[i] = 1;
    12                 if(match[i]==-1||find(match[i])) {
    13                     match[i] = x;
    14                     return true;
    15                 }
    16             }
    17         }
    18         return false;
    19     }
    20     static int hungary() {
    21         int ans = 0;
    22         Arrays.fill(match, -1);
    23         for(int i=1;i<=p;i++) {
    24             Arrays.fill(used, 0);
    25             if(find(i))
    26                 ans++;
    27         }
    28         return ans;
    29     }
    30     public static void main(String[] args) {
    31         Scanner cin = new Scanner(System.in);
    32         casen = cin.nextInt();
    33         while(casen-->0) {
    34             p = cin.nextInt();
    35             n = cin.nextInt();
    36             match = new int [310];
    37             used = new int [310];
    38             link = new int [310][310];
    39             for(int i=1;i<=p;i++) {
    40                 int k = cin.nextInt();
    41                 while(k-->0) {
    42                     int x = cin.nextInt();
    43                     link[i][x] = 1;
    44                 }
    45             }
    46             int ans = hungary();
    47             if(ans==p)
    48                 System.out.println("YES");
    49             else
    50                 System.out.println("NO");
    51         }
    52     }
    53 }

    dfs搜索

    给出你一个无向图,然后对其中的点去上色, 只能上黑色和白色,要求是黑色点不能相邻(白色可以相邻),问最多能上多少黑色的顶点。

    1
    6 8
    1 2
    1 3
    2 4
    2 5
    3 4
    3 6
    4 6
    5 6

    Sample Output

    3
    1 4 5
     1 import java.util.ArrayList;
     2 import java.util.Scanner;
     3 
     4 public class Main{
     5     static int [] vis,res;
     6     static int n,ans;
     7     static ArrayList<Integer> [] v = new ArrayList[110];
     8     static void dfs(int pos,int sum) {
     9         if(pos==n+1) {
    10             if(sum>ans) {
    11                 ans = sum;
    12                 int cnt = 0;
    13                 for(int i=1;i<=n;i++) {
    14                     if(vis[i]==1)
    15                         res[cnt++] = i;
    16                 }
    17             }
    18             return;
    19         }
    20         int flag = 0;
    21         for(int i=0;i<v[pos].size();i++) {
    22             if(vis[v[pos].get(i)]==1) {
    23                 flag = 1;
    24                 break;
    25             }
    26         }
    27         if(flag==0) {
    28             vis[pos] = 1;
    29             dfs(pos+1, sum+1);
    30             vis[pos] = 0;
    31         }
    32         dfs(pos+1, sum);
    33     }
    34     public static void main(String[] args) {
    35         Scanner cin = new Scanner(System.in);
    36         int casen = cin.nextInt();
    37         while(casen-->0) {
    38             n = cin.nextInt();
    39             ans = 0;
    40             res = new int [n+10];
    41             vis = new int [n+10];
    42             for(int i=0;i<n+10;i++)
    43                 v[i] = new ArrayList<Integer>();
    44             int m = cin.nextInt();
    45             for(int i=0;i<m;i++) {
    46                 int x = cin.nextInt();
    47                 int y = cin.nextInt();
    48                 v[x].add(y);
    49                 v[y].add(x);
    50             }
    51             dfs(1, 0);
    52             System.out.println(ans);
    53             for(int i=0;i<ans;i++)
    54                 System.out.print(res[i]+" ");
    55         }
    56     }
    57 }

     05.21

    错排

    N个数,有M个错排的组合数

     1 import java.util.Scanner;
     2 
     3 public class Main {
     4     static long [][] c = new long [30][30];
     5     static int n,m;
     6     static void init() {
     7         c[0][0] = 1;
     8         for(int i=1;i<=25;i++) {
     9             c[i][0] = 1;
    10             for(int j=1;j<=i;j++) {
    11                 if(j<=i/2)
    12                     c[i][j] = c[i-1][j]+c[i-1][j-1];
    13                 else
    14                     c[i][j] = c[i][i-j];
    15             }
    16         }
    17     }
    18     static void init2() {
    19         c[0][0] = 1;
    20         for(int i=1;i<=25;i++) {
    21             c[i][0] = 1;
    22             c[i][i] = 1;
    23             for(int j=1;j<i;j++)
    24                 c[i][j] = c[i-1][j-1]+c[i-1][j];
    25         }
    26     }
    27     public static void main(String[] args) {
    28         Scanner cin = new Scanner(System.in);
    29         int casen = cin.nextInt();
    30         long [] dp = new long [30];
    31         dp[0] = 0;
    32         dp[1] = 0;
    33         dp[2] = 1;
    34         init2();
    35         for(int i=3;i<30;i++)
    36             dp[i] = (i-1)*(dp[i-1]+dp[i-2]);
    37         while(casen-->0) {
    38             n = cin.nextInt();
    39             m = cin.nextInt();
    40             System.out.println(dp[m]*c[n][m]);
    41         }
    42     }
    43 }

    kmp:

    给定两个数组,问能不能再第一个数组中匹配得到第二个数组,如果可以,那么输出最早匹配的起始位置,否则输出-1

     1 import java.util.Scanner;
     2 
     3 public class Main {
     4     static int n,m;
     5     static int [] s,t;
     6     static int [] next;
     7     static void getnext() {
     8         next[0] = -1;
     9         int i=0,j=-1;
    10         while(i<m) {
    11             if(j==-1||t[i]==t[j]) {
    12                 ++i;
    13                 ++j;
    14                 next[i] = j;
    15             }
    16             else
    17                 j = next[j];
    18         }
    19 
    20     }
    21     static int kmp() {
    22         int i=0,j=0;
    23         while(i<n&&j<m) {
    24             if(j==-1||s[i]==t[j]) {
    25                 ++i;
    26                 ++j;
    27             }
    28             else
    29                 j = next[j];
    30         }
    31         if(j==m) {
    32             return i-m+1;
    33         }
    34         else
    35             return -1;
    36     }
    37     public static void main(String[] args) {
    38         Scanner cin = new Scanner(System.in);
    39         int casen = cin.nextInt();
    40         while(casen-->0) {
    41             n = cin.nextInt();
    42             m = cin.nextInt();
    43             s = new int [n+10];
    44             t = new int [m+10];
    45             next = new int [m+10];
    46             for(int i=0;i<n;i++)
    47                 s[i] = cin.nextInt();
    48             for(int i=0;i<m;i++)
    49                 t[i] = cin.nextInt();
    50             getnext();
    51             System.out.println(kmp());
    52         }
    53     }
    54 }

    kmp求循环节:

    字符串长度为N,循环节长度为N-next[N],

    给一个字符串,问这个字符串是否能由另一个字符串重复R次得到,求R的最大值。

     1 import java.util.Scanner;
     2 
     3 public class Main {
     4     static int n;
     5     static char [] s;
     6     static int [] next;
     7     static void getnext() {
     8         next[0] = -1;
     9         int i=0,j=-1;
    10         while(i<n) {
    11             if(j==-1||s[i]==s[j]) {
    12                 ++i;
    13                 ++j;
    14                 next[i] = j;
    15             }
    16             else
    17                 j = next[j];
    18         }
    19     }
    20     public static void main(String[] args) {
    21         Scanner cin = new Scanner(System.in);
    22         int ca = 1;
    23         while(cin.hasNext()) {
    24             String ss = cin.nextLine();
    25             if(ss.equals("."))
    26                 break;
    27             n = ss.length();
    28             next = new int [n+10];
    29             s = ss.toCharArray();
    30             getnext();
    31             
    32             int len = n-next[n];
    33             if(n%len==0) {
    34                 System.out.println(n/len);
    35             }else {
    36                 System.out.println(1);
    37             }
    38         }
    39     }
    40 }

    搜索

    在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
    Input
    输入含有多组测试数据。
    每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
    当为-1 -1时表示输入结束。
    随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
    Output
    对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。
    Sample Input
    2 1
    #.
    .#
    4 4
    ...#
    ..#.
    .#..
    #...
    -1 -1
    
    Sample Output
    2
    1
    
     1 import java.util.Scanner;
     2 
     3 public class Main {
     4     static int k,n;
     5     static String [] s = new String[10];
     6     static int [] vish = new int[10];
     7     static int [] viss = new int[10];
     8     static char[][] a = new char[10][10];
     9     static int ans = 0;
    10     static void dfs(int x,int step) {
    11         if(step>=k) {
    12             ans++;
    13             return;
    14         }
    15         for(int i=x;i<n;i++) {
    16             for(int j=0;j<n;j++) {
    17                 if(vish[i]==0&&viss[j]==0&&a[i][j]=='#') {
    18                     viss[j] = 1;
    19                     vish[i] = 1;
    20                     dfs(i+1, step+1);
    21                     vish[i] = 0;
    22                     viss[j] = 0;
    23                 }
    24             }
    25         }
    26     }
    27     public static void main(String[] args) {
    28         Scanner cin = new Scanner(System.in);
    29         while(cin.hasNext()) {
    30             ans = 0;
    31             n = cin.nextInt();
    32             k = cin.nextInt();
    33             if(n==-1&&k==-1)
    34                 break;
    35             for(int i=0;i<vish.length;i++)
    36                 vish[i] = 0;
    37             for(int i=0;i<viss.length;i++)
    38                 viss[i] = 0;
    39             for(int i=0;i<n;i++)
    40                 s[i] = cin.next();
    41             for(int i=0;i<n;i++) {
    42                 for(int j=0;j<n;j++) {
    43                     a[i][j] = s[i].charAt(j);
    44                 }
    45             }//
    46             dfs(0, 0);
    47             System.out.println(ans);
    48         }
    49         
    50     }
    51 }

     05.22

    LCA:

    求树上两点最短距离

     1 import java.util.Arrays;
     2 import java.util.Scanner;
     3 class node{
     4     int to;
     5     int val;
     6     int next;
     7 }
     8 public class Main {
     9     static int n,q;
    10     static int [] head,dis,depth;
    11     static node [] e;
    12     static int cnt = 0;
    13     static int [][] f;
    14     static void add(int x,int y,int w) {
    15         e[cnt].to = y;
    16         e[cnt].val = w;
    17         e[cnt].next = head[x];
    18         head[x] = cnt++;
    19     }
    20     static void dfs(int x,int fa) {
    21         f[x][0] = fa;
    22         for(int i=head[x];i!=-1;i=e[i].next) {
    23             int to = e[i].to;
    24             if(to!=fa) {
    25                 dis[to] = dis[x]+e[i].val;
    26                 depth[to] = depth[x] + 1;
    27                 dfs(to, x);
    28             }
    29         }
    30     }
    31     static void init() {
    32         depth[1] = 1;
    33         dis[1] = 0;
    34         dfs(1, 0);
    35         //设fa[i][j]表示i结点的第2^j个祖先,显然有
    36         for(int j=1;(1<<j)<=n;j++) {
    37             for(int i=1;i<=n;i++) {
    38                 //System.out.println("i="+i+" j-1="+(j-1)+f[i][j-1]);
    39                 f[i][j] = f[f[i][j-1]][j-1];
    40             }
    41         }
    42     }
    43     static int lca(int x,int y) {
    44         if(depth[x]<depth[y]) {
    45             int a = x ;
    46             x = y;
    47             y = a;
    48         }
    49         for(int i=20;i>=0;i--) {
    50             if(depth[f[x][i]]>=depth[y]) {
    51                 x = f[x][i];
    52                 if(x==y)
    53                     return x;
    54             }
    55         }
    56         for(int i=20;i>=0;i--) {
    57             if(f[x][i]!=f[y][i]) {
    58                 x = f[x][i];
    59                 y = f[y][i];
    60             }
    61         }
    62         return f[x][0];
    63     }
    64     public static void main(String[] args) {
    65         Scanner cin = new Scanner(System.in);
    66         int casen = cin.nextInt();
    67         while(casen-->0) {
    68             cnt = 0;
    69             n = cin.nextInt();
    70             q = cin.nextInt();
    71             f = new int [40000+10][21];
    72             e = new node[160000+10];
    73             head = new int [40000+10];
    74             dis = new int [40000+10];
    75             depth = new int [40000+10];
    76             Arrays.fill(head, -1);
    77             for(int i=0;i<=n<<2;i++)
    78                 e[i] = new node();
    79             for(int i=0;i<n-1;i++) {
    80                 int x = cin.nextInt();
    81                 int y = cin.nextInt();
    82                 int w = cin.nextInt();
    83                 add(x, y, w);
    84                 add(y, x, w);
    85             }
    86             init();
    87             
    88             while(q-->0) {
    89                 int x = cin.nextInt();
    90                 int y = cin.nextInt();
    91                 System.out.println(dis[x]+dis[y]-2*dis[lca(x, y)]);
    92                 
    93             }
    94             System.out.println();
    95         }
    96     }
    97 }
    http://codevs.cn/problem/1036/
    1
    #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=3e4+10; 7 int path[maxn]; 8 struct node{ 9 int to; 10 int val; 11 int nex; 12 }e[maxn<<2]; 13 int f[maxn][22]; 14 int head[maxn],dis[maxn],depth[maxn]; 15 int n,cnt; 16 void add(int x,int y,int w){ 17 e[cnt].to=y; 18 e[cnt].val=w; 19 e[cnt].nex=head[x]; 20 head[x]=cnt++; 21 } 22 void dfs(int x,int fa) 23 { 24 f[x][0]=fa; 25 for(int i=head[x];i!=-1;i=e[i].nex) 26 { 27 int to=e[i].to; 28 if(to!=fa) 29 { 30 dis[to]=dis[x]+e[i].val; 31 depth[to]=depth[x]+1; 32 dfs(to,x); 33 } 34 } 35 } 36 void init() 37 { 38 depth[1]=1; 39 dis[1]=0; 40 dfs(1,0); 41 for(int j=1;(1<<j)<=n;j++) 42 { 43 for(int i=1;i<=n;i++) 44 { 45 f[i][j]=f[f[i][j-1]][j-1]; 46 } 47 } 48 } 49 int lca(int x,int y) 50 { 51 if(depth[x]<depth[y]) 52 { 53 swap(x,y); 54 } 55 int dis=depth[x]-depth[y]; 56 for(int i=0;i<=20;i++) 57 { 58 if((1<<i)&dis) 59 { 60 x=f[x][i]; 61 } 62 } 63 if(x==y) 64 return x; 65 for(int i=20;i>=0;i--) 66 { 67 if(f[x][i]!=f[y][i]) 68 { 69 x=f[x][i]; 70 y=f[y][i]; 71 } 72 } 73 return f[x][0]; 74 } 75 int main() 76 { 77 scanf("%d",&n);memset(head,-1,sizeof(head)); 78 for(int i=0;i<n-1;i++) 79 { 80 int x,y; 81 scanf("%d%d",&x,&y); 82 add(x,y,1); 83 add(y,x,1); 84 } 85 init(); 86 int m; 87 cin>>m; 88 89 for(int i=0;i<m;i++) 90 { 91 scanf("%d",&path[i]); 92 } 93 int ans=0; 94 for(int i=0;i<m-1;i++) 95 { 96 ans+=dis[path[i]]+dis[path[i+1]]-2*dis[lca(path[i],path[i+1])]; 97 } 98 printf("%d ",ans); 99 }

     05.23

    树的直径

    求树上相距最远两点的距离

     1 import java.util.ArrayDeque;
     2 import java.util.Arrays;
     3 import java.util.Scanner;
     4 class node{
     5     int to;
     6     int w;
     7     int next;
     8 }
     9 public class Main {
    10     static node [] e = new node[100000];
    11     static int [] head = new int [10000];
    12     static int [] dis = new int [10000];
    13     static int [] vis = new int [10000];
    14     static int cnt = 0,ed,sum;
    15     static void add(int x,int y,int w) {
    16         e[cnt].to = y;
    17         e[cnt].w = w;
    18         e[cnt].next = head[x];
    19         head[x] = cnt++;
    20         
    21     }
    22     static void bfs(int x) {
    23         ArrayDeque<Integer> q = new ArrayDeque<Integer>();
    24         q.offer(x);
    25         Arrays.fill(vis, 0);
    26         Arrays.fill(dis, 0);
    27         vis[x] = 1;
    28         sum = 0;
    29         while(!q.isEmpty()) {
    30             int pos = q.poll();
    31             for(int i=head[pos];i!=-1;i=e[i].next) {
    32                 int to = e[i].to;
    33                 if(vis[to]==0) {
    34                     vis[to] = 1;
    35                     dis[to] = dis[pos] + e[i].w;
    36                     if(sum<dis[to]) {
    37                         sum = dis[to];
    38                         ed = to;
    39                     }
    40                     q.offer(to);
    41                 }
    42             }
    43         }
    44     }
    45     public static void main(String[] args) {
    46         Scanner cin = new Scanner(System.in);
    47         for(int i=0;i<100000;i++)
    48             e[i] = new node();
    49         Arrays.fill(head, -1);
    50         while(cin.hasNext()) {
    51             int x = cin.nextInt();
    52             int y = cin.nextInt();
    53             int w = cin.nextInt();
    54             add(x, y, w);
    55             add(y, x, w);
    56         }
    57         bfs(1);
    58         bfs(ed);
    59     
    60         System.out.println(sum);
    61     }
    62 }

    拓扑排序:

     1 import java.util.ArrayDeque;
     2 import java.util.Arrays;
     3 import java.util.PriorityQueue;
     4 import java.util.Scanner;
     5 class node{
     6     int to;
     7     int nex;
     8 }
     9 public class Main{
    10     static int n,m,cnt,t;
    11     static node [] e;
    12     static int [] head,in,ans;
    13     static void add(int x,int y) {
    14         e[cnt].to = y;
    15         e[cnt].nex = head[x];
    16         head[x] = cnt++;
    17     }
    18     static void topu() {
    19         PriorityQueue<Integer>q = new PriorityQueue<Integer>();
    20         for(int i=1;i<=n;i++) {
    21             if(in[i]==0)
    22                 q.offer(i);
    23         }
    24         t = 0;
    25         while(!q.isEmpty()) {
    26             int pos = q.poll();
    27             ans[t++] = pos;
    28             for(int i=head[pos];i!=-1;i=e[i].nex){
    29                 int to = e[i].to;
    30                 in[to]--;
    31                 if(in[to]==0)
    32                     q.offer(to);
    33             }
    34         }
    35     }
    36     public static void main(String[] args) {
    37         Scanner cin = new Scanner(System.in);
    38         while(cin.hasNext()) {
    39             cnt = 0;
    40             t = 0;
    41             n = cin.nextInt();
    42             m = cin.nextInt();
    43             e = new node[m+10];
    44             for(int i=0;i<m+5;i++)
    45                 e[i] = new node();
    46             head = new int [n+10];
    47             in = new int [n+10];
    48             ans = new int [n+10];
    49             Arrays.fill(head, -1);
    50             for(int i=0;i<m;i++) {
    51                 int x = cin.nextInt();
    52                 int y = cin.nextInt();
    53                 add(x, y);
    54                 in[y]++;
    55             }
    56             topu();
    57             for(int i=0;i<t-1;i++)
    58                 System.out.print(ans[i]+" ");
    59             System.out.println(ans[t-1]);
    60         }
    61     }
    62 }

     manacher

    import java.util.Collection;
    import java.util.PriorityQueue;
    import java.util.Scanner;
    
    public class Main{
        static String s,t;
        static int [] r;
        static int manacher(int n) {
            int  cnt = 0;
            t = "";
            t+="$#";
            for(int i=0;i<n;i++) {
                t+=s.charAt(i);
                t+="#";
            }
            //System.out.println(t);
            int pos = 0,rx = 0,ans = 1;
            cnt = t.length();;
            for(int i=1;i<cnt;i++) {
                r[i]=(rx>i)?Math.min(r[2*pos-i], rx-i):1;
                
                while(i-r[i]>=0&&i+r[i]<cnt&&t.charAt(i-r[i])==t.charAt(i+r[i]))
                    r[i]++;
                if(rx<i+r[i]) {
                    rx = i+r[i];
                    pos = i;
                }
                if(ans<r[i] - 1 )
                    ans = r[i]-1;
            }
            return ans;
        }
        public static void main(String[] args) {
            Scanner cin = new Scanner(System.in);
            while(cin.hasNext()) {
                s = cin.next();
                if(s.equals("END"))
                    break;
                r = new int [1000000*2+10];
                
                System.out.println(manacher(s.length()));
            }
        }
    }

    一些JAVA知识点:

    import  java.util.*;
    
    public class xx {
        
        
        static class cmp implements Comparator<LLong>{
            @Override
            public int compare(LLong o1, LLong o2) {
                return (int) (o2.val - o1.val);
            }
        }
        
        static List<LLong> list = new ArrayList<LLong>();
        static Queue<LLong> qu = new LinkedList<LLong>();
        static Deque<Integer> quee = new LinkedList<Integer>();
        static PriorityQueue<LLong> que = new PriorityQueue<LLong>();
        static Set<LLong> set = new TreeSet<LLong>(); 
        static Map<Integer,Set<Integer>> map = new TreeMap<Integer, Set<Integer>>();
        
        static class LLong implements Comparable<LLong>{
            int x;
            long val;
            String s;
            
            @Override
            public int compareTo(LLong o) {
                if(this.x == o.x)
                    return (int) (this.val - o.val);
                else if(this.x >= o.x)
                    return (int) (o.val - this.val);
                else
                    return (this.s).compareTo(o.s); 
                    
            }
        }
        
        public static void main(String[] args) {
            
            Collections.sort(list, new cmp()); 
            
            Collections.sort(list, new Comparator<LLong>() {
                @Override
                public int compare(LLong o1, LLong o2) {
                    return (int) (o2.val-o1.val);
                }
            });
            
            
        }
    }
    Input输入数据首先包含一个正整数C,表示有C组测试用例,每组测试用例的第一行是两个整数n和m(1<=n<=100, 1<=m<=100),分别表示经费的金额和大米的种类,然后是m行数据,每行包含3个数p,h和c(1<=p<=20,1<=h<=200,1<=c<=20),分别表示每袋的价格、每袋的重量以及对应种类大米的袋数。Output对于每组测试数据,请输出能够购买大米的最多重量,你可以假设经费买不光所有的大米,并且经费你可以不用完。每个实例的输出占一行。Sample Input
    1
    8 2
    2 100 4
    4 100 2
    Sample Output
    400
     1 #include<iostream>  
     2 #include<stdio.h>  
     3 #include<algorithm>  
     4 #include<cstring>   
     5 using namespace std;  
     6 int c[11000],w[11000],num[11000];  
     7 int dp[11000];  
     8 int m,n,tip;
     9 int casen;
    10 void ZeroOnePack(int c, int w)  
    11 {  
    12     for(int v =n; v >=c; v--)  
    13     {  
    14         dp[v] = max(dp[v],dp[v-c]+w);  
    15     }  
    16 }  
    17   
    18 void CompletePack(int c, int w)  
    19 {  
    20     for(int v = c; v <= n; v++)  
    21     {  
    22         dp[v] = max(dp[v],dp[v-c]+w);  
    23     }  
    24 }  
    25   
    26 void MultiplePack(int c, int w, int num)  
    27 {  
    28     if(c*num>=n)  
    29     {  
    30         CompletePack(c,w);  
    31     }  
    32     else  
    33     {  
    34         int k = 1;  
    35         while(k < num)  
    36         {  
    37             ZeroOnePack(k*c, k*w);  
    38             num -= k;  
    39             k <<= 1;  
    40         }  
    41         ZeroOnePack(num*c, num*w);  
    42     }  
    43 }  
    44 int main()  
    45 {  
    46         scanf("%d",&casen);
    47         while(casen--)
    48         { 
    49         scanf("%d%d",&n,&m);  
    50         for(int i = 1; i <=m; i++)  
    51         {  
    52             scanf("%d%d%d",&c[i], &w[i], &num[i]);  
    53         }  
    54         memset(dp,0,sizeof(dp));  
    55         for(int i = 1; i <=m; i++)  
    56         {  
    57             MultiplePack(c[i],w[i],num[i]);  
    58         }  
    59         printf("%d
    ",dp[n]);  
    60         }
    61     return 0;  
    62 }  
  • 相关阅读:
    1019.安全技能树
    1020.Burp Suite扩展之Java-Deserialization-Scanner
    1018.渗透利器
    1016.XXE漏洞攻防学习
    1017.前端黑在线工具
    1015.WebGoat SQL注入之 Order by注入解题思路
    1014.WebGoat SQL盲注 解题思路
    2019春节防坑指南之抢票陷阱(文末有彩蛋)
    【年度大戏】勒索”嘿客“无间道之战
    470余万条疑似12306用户数据遭贩卖 嫌疑人被刑拘
  • 原文地址:https://www.cnblogs.com/1013star/p/10877988.html
Copyright © 2020-2023  润新知