# AP325 補救計畫(I) 作者:欉恩祁 因為我跟竑誠在APCS被其他人給電爛了,所以決定來寫TCIRC的神奇題目來補救。 [>>Part II](https://hackmd.io/@r1cky/rJjSMrQ5Y) --- ## d001~d020 ### d001 合成函數(1) 解法:遞迴 ```Java= import java.io.*; public class d001 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static long ret,r; public static boolean neg; public static void main(String[] args) throws Exception{ System.out.println(orz()); } public static long f() throws Exception{ return 2*orz()-1; } public static long g() throws Exception{ return orz()+2*orz()-3; } public static long orz() throws Exception{ ret=0; r=br.read(); neg=false; if(r=='f') { r=br.read(); return f(); } else if(r=='g') { r=br.read(); return g(); } else if(r=='-') { neg=true; r=br.read(); } while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } if(neg)ret*=-1; return ret; } } ``` --- ### d002 合成函數(2) 解法:遞迴 ```Java= import java.io.*; public class d002 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static long ret,r; public static boolean neg; public static void main(String[] args) throws Exception{ System.out.println(orz()); } public static long f() throws Exception{ return 2*orz()-3; } public static long g() throws Exception{ return 2*orz()+orz()-7; } public static long h() throws Exception{ return 3*orz()-2*orz()+orz(); } public static long orz() throws Exception{ ret=0; r=br.read(); neg=false; if(r=='f') { r=br.read(); return f(); } else if(r=='g') { r=br.read(); return g(); } else if(r=='h') { r=br.read(); return h(); } else if(r=='-') { neg=true; r=br.read(); } while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } if(neg)ret*=-1; return ret; } } ``` --- ### d003 棍子中點切割 解法:遞迴(魔王題,切中點要開double不然會卡測資:/) ```Java= import java.io.*; import java.util.*; public class d003 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static int[] cut=new int[200005]; public static void main(String[] args) throws Exception{ final int n=orz(); final int l=orz(); cut[0]=0; for(int i=1;i<=n;i++) cut[i]=orz(); cut[n+1]=l; System.out.println(rec(0,n+1)); } public static long rec(int l,int r) { if(l+1==r)return 0; double mid=((double)cut[l]+cut[r])/2; double d=1<<30; int c=-1; for(int i=l+1;i<r;i++) { if(Math.abs(cut[i]-mid)<d) { d=Math.abs(cut[i]-mid); c=i; } } return rec(l,c)+rec(c,r)+cut[r]-cut[l]; } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d004 支點切割 解法:前綴和、數學 ```Java import java.io.*; public class d004 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,k; public static long rt=0; public static int[] mp=new int[50005]; public static long[] ls=new long[50005]; public static long[] rs=new long[50005]; public static long[] lss=new long[50005]; public static long[] rss=new long[50005]; public static void main(String[] args) throws Exception{ final int n=orz(); k=orz(); for(int i=1;i<=n;i++)mp[i]=orz(); ls[0]=lss[0]=0; rs[n+1]=rss[n+1]=0; for(int i=1;i<=n;i++)ls[i]=ls[i-1]+mp[i]; for(int i=1;i<=n;i++)lss[i]=lss[i-1]+ls[i]; for(int i=n;i>0;i--)rs[i]=rs[i+1]+mp[i]; for(int i=n;i>0;i--)rss[i]=rss[i+1]+rs[i]; cut(1,n,0); System.out.println(rt); } public static void cut(int l,int r,int c) { if(c==k||l+1>=r)return; long min=1L<<60,t; int p=-1; for(int i=l+1;i<r;i++) { t=Math.abs(lss[i-1]-lss[l-1]-ls[l-1]*(i-l)-rss[i+1]+rss[r+1]+rs[r+1]*(r-i)); if(t<min) { min=t; p=i; } } rt+=mp[p]; cut(l,p-1,c+1); cut(p+1,r,c+1); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d005 二維黑白影像編碼 解法:遞迴 ```Java= import java.io.*; public class d005 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,p=0; public static long rt=0; public static String in; public static void main(String[] args) throws Exception{ in=br.readLine(); int l=orz(); switch(in.charAt(p)) { case '0': break; case '1': rt+=l*l; break; case '2': rec(l/2); break; } System.out.println(rt); } public static void rec(int l) { for(int i=0;i<4;i++) { p++; switch(in.charAt(p)) { case '0': break; case '1': rt+=l*l; break; case '2': rec(l/2); break; } } } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d006 子集合乘積 解法:暴力窮舉 ```Java= mport java.io.*; public class d006 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,t,p=10009; public static int[] in=new int[25]; public static long rt=0; public static void main(String[] args) throws Exception{ t=orz(); for(int i=0;i<t;i++)in[i]=orz(); force(0,1); System.out.println(rt-1); } public static void force(int id,long x) { if(id==t) { if(x==1)rt++; return; } force(id+1,(x*in[id])%p); force(id+1,x); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d007 子集合的和 解法:暴力窮舉 ```Java= import java.io.*; public class d007 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,t,p; public static int[] in=new int[25]; public static long max=0; public static void main(String[] args) throws Exception{ t=orz(); p=orz(); for(int i=0;i<t;i++)in[i]=orz(); force(0,0); System.out.println(max); } public static void force(int id,long x) { if(id==t) { if(x<p&&x>max) { max=x; } return; } force(id+1,x+in[id]); force(id+1,x); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d008 最多得分的皇后 解法:遞迴、undo ```Java= import java.util.*; import java.io.*; public class d008 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int n; public static int[][] mp=new int[15][15]; public static int[][] cs=new int[15][15];//current state public static int mux=-(1<<30);//-inf public static void main(String[] args) throws Exception{ String[] in=br.readLine().split(" "); n=Integer.parseInt(in[0]); for(int i=0;i<n;i++) { in=br.readLine().split(" "); for(int j=0;j<n;j++) { mp[i][j]=Integer.parseInt(in[j]); } } fill(0,0); System.out.println(mux); } public static void fill(int x,int c) { if(x==n) { mux=Math.max(mux,c); return; } fill(x+1,c); for(int y=0;y<n;y++) { if(cs[x][y]==0) { for(int i=y-1;i>=0;i--) { cs[x][i]++; } for(int i=y+1;i<n;i++) { cs[x][i]++; } for(int i=x-1;i>=0;i--) { cs[i][y]++; } for(int i=x+1;i<n;i++) { cs[i][y]++; } for(int i=x-1,j=y-1;i>=0&&j>=0;i--,j--) { cs[i][j]++; } for(int i=x+1,j=y+1;i<n&&j<n;i++,j++) { cs[i][j]++; } for(int i=x-1,j=y+1;i>=0&&j<n;i--,j++) { cs[i][j]++; } for(int i=x+1,j=y-1;i<n&&j>=0;i++,j--) { cs[i][j]++; } cs[x][y]++; fill(x+1,c+mp[x][y]); for(int i=y-1;i>=0;i--) { cs[x][i]--; } for(int i=y+1;i<n;i++) { cs[x][i]--; } for(int i=x-1;i>=0;i--) { cs[i][y]--; } for(int i=x+1;i<n;i++) { cs[i][y]--; } for(int i=x-1,j=y-1;i>=0&&j>=0;i--,j--) { cs[i][j]--; } for(int i=x+1,j=y+1;i<n&&j<n;i++,j++) { cs[i][j]--; } for(int i=x-1,j=y+1;i>=0&&j<n;i--,j++) { cs[i][j]--; } for(int i=x+1,j=y-1;i<n&&j>=0;i++,j--) { cs[i][j]--; } cs[x][y]--; } } } } ``` --- ### d009 刪除邊界 解法:遞迴、dp ```Java= import java.util.*; import java.io.*; public class d009 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int r,ret; public static int[][] mp=new int[15][15]; public static void main(String[] args) throws Exception{ final int n=orz(); final int m=orz(); for(int i=0;i<n;i++)for(int j=0;j<m;j++)mp[i][j]=orz(); System.out.println(dp(0,n-1,0,m-1)); } public static int dp(int lx,int rx,int ly,int ry) { if(lx==rx||ly==ry)return 0; int m=Math.min(dp(lx+1,rx,ly,ry)+cut(lx,lx,ly,ry),dp(lx,rx-1,ly,ry)+cut(rx,rx,ly,ry)); m=Math.min(dp(lx,rx,ly+1,ry)+cut(lx,rx,ly,ly),m); m=Math.min(dp(lx,rx,ly,ry-1)+cut(lx,rx,ry,ry),m); return m; } public static int cut(int lx,int rx,int ly,int ry) { int cnt=0,c=0; for(int i=lx;i<=rx;i++) { for(int j=ly;j<=ry;j++) { if(mp[i][j]==0) { cnt++; } else { c++; } } } return Math.min(cnt,c); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d010 不同的數—排序 解法:排序、set ```Java= import java.io.*; import java.util.*; public class d010 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out)); public static int ret,r; public static boolean neg; public static void main(String[] args) throws Exception{ final int t=orz(); HashSet<Integer> s=new HashSet<>(); PriorityQueue<Integer> pq=new PriorityQueue<>(new Comparator<Integer>() { public int compare(Integer f,Integer s) { if(f>s)return 1; if(f==s)return 0; return -1; } }); for(int i=0;i<t;i++)s.add(orz()); bw.write(s.size()+"\n"); for(int i:s)pq.offer(i); while(!pq.isEmpty())bw.write(pq.poll()+" "); bw.flush(); } public static int orz() throws Exception{ ret=0; neg=false; r=br.read(); if(r=='-') { neg=true; r=br.read(); } while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } if(neg)ret*=-1; return ret; } } ``` --- ### d011 離散化 – sort 解法:排序、map ```Java= import java.io.*; import java.util.*; public class d011 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out)); public static int ret,r,in; public static boolean neg; public static void main(String[] args) throws Exception{ final int t=orz(); HashSet<Integer> s=new HashSet<>(); Queue<Integer> q=new LinkedList<>(); for(int i=0;i<t;i++) { in=orz(); s.add(in); q.offer(in); } ArrayList<Integer> al=new ArrayList<>(s); Collections.sort(al); HashMap<Integer,Integer> mp=new HashMap<>(); for(int i=0;i<al.size();i++) { mp.put(al.get(i),i); } while(!q.isEmpty())bw.write(mp.get(q.poll())+" "); bw.flush(); } public static int orz() throws Exception{ ret=0; neg=false; r=br.read(); if(r=='-') { neg=true; r=br.read(); } while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } if(neg)ret*=-1; return ret; } } ``` --- ### d012 快速冪 解法:快速冪 ```Java= import java.io.*; public class d012 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,x,y,p; public static boolean neg; public static void main(String[] args) throws Exception{ x=orz(); y=orz(); p=orz(); System.out.println(f(y)); } public static long f(int y) throws Exception{ if(y==0)return 1; if(y==1)return x; long a; a=f(y/2); if(y%2==0) { return (a*a)%p; } return (((a*a)%p)*x)%p; } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d013 快速冪--200 位整數 解法:快速冪、數學 ```Java= import java.io.*; public class d013 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static long ret; public static int r,x,y,p; public static String[] in; public static void main(String[] args) throws Exception{ in=br.readLine().split(" "); y=Integer.parseInt(in[1]); p=Integer.parseInt(in[2]); x=premod(); System.out.println(f((int)y)); } public static long f(int y) throws Exception{ if(y==0)return 1; if(y==1)return x; long a; a=f(y/2); if(y%2==0) { return a*a%p; } return ((a*a)%p*x)%p; } public static int premod() throws Exception{ int pt=-1; ret=0; while(pt<in[0].length()-1) { pt++; ret*=10; r=in[0].charAt(pt); ret+=(r&15); ret%=p; } return (int)ret; } } ``` --- ### d014 快速計算費式數列第 n 項 解法:快速冪、矩陣 ```Java= import java.io.*; public class d014 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out)); public static int ret,r,n; public static final int p=(int)Math.pow(10,9)+7; public static void main(String[] args) throws Exception{ n=orz(); while(n!=-1) { bw.write((fib(n-1).t[0][0])+"\n"); n=orz(); } bw.flush(); } public static matrix fib(int y) throws Exception{ if(y==-1)return new matrix(0,0,0,0); if(y==0||y==1)return new matrix(1,1,1,0); matrix a=fib(y/2); if(y%2==0) { return x(a,a); } return x(x(a,a),new matrix(1,1,1,0)); } public static matrix x(matrix u,matrix v) throws Exception{ long a=u.t[0][0]*v.t[0][0]+u.t[0][1]*v.t[1][0]; long b=u.t[0][0]*v.t[0][1]+u.t[0][1]*v.t[1][1]; long c=u.t[1][0]*v.t[0][0]+u.t[1][1]*v.t[1][0]; long d=u.t[1][0]*v.t[0][1]+u.t[1][1]*v.t[1][1]; return new matrix(a%p,b%p,c%p,d%p); } public static int orz() throws Exception{ ret=0; r=br.read(); if(r=='-')return -1; while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } class matrix{ long[][] t=new long[2][2]; matrix(long a,long b,long c,long d) { t[0][0]=a; t[0][1]=b; t[1][0]=c; t[1][1]=d; } } ``` --- ### d015 Two-Number problem 解法:排序 ```Java= import java.io.*; import java.util.*; public class d015 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static void main(String[] args) throws Exception{ String[] in=br.readLine().split(" "); final int m=Integer.parseInt(in[0]); final int n=Integer.parseInt(in[1]); final int k=Integer.parseInt(in[2]); int[] a=new int[m]; int[] b=new int[n]; int begin=n-1,ans=0; in=br.readLine().split(" "); for(int i=0;i<m;i++)a[i]=Integer.parseInt(in[i]); in=br.readLine().split(" "); for(int i=0;i<n;i++)b[i]=Integer.parseInt(in[i]); Arrays.sort(a); Arrays.sort(b); for(int i=0;i<m;i++) { for(int j=begin;j>=0;j--,begin--) { if(a[i]+b[j]<k)break; if(a[i]+b[j]==k)ans++; } } System.out.println(ans); } } ``` --- ### d016 互補團隊 解法:位元運算 ```Java= import java.io.*; import java.util.*; public class d016 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static long[] cp; public static void main(String[] args) throws Exception{ long ans=0; String[] in=br.readLine().split(" "); int m=Integer.parseInt(in[0]); int n=Integer.parseInt(in[1]); cp=new long[n]; getline(n,m); Arrays.parallelSort(cp); final long tg=(1L<<(m))-1; long ck; int ch=n-1; for(int i=0;i<n;i++) { for(int j=ch;j>i;j--) { ck=cp[i]+cp[j]; if(ck>tg)ch--; else if(ck<tg)break; else { ans++; } } } System.out.println(ans); } public static void getline(int n,int m) throws Exception { long ret=0; long a; for(int i=0;i<n;i++) { a=br.read(); while(a>64&&a<91) { ret|=(1L<<(a-65)); a=br.read(); } cp[i]=ret; ret=0; } } } ``` ### d017 模逆元 解法:費馬小定理、快速冪 ```Java= import java.io.*; public class d017 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out)); public static int ret,r,p,x; public static void main(String[] args) throws Exception{ final int n=orz(); p=orz(); for(int i=0;i<n;i++) { x=orz(); bw.write(f(p-2)+" "); } bw.flush(); } public static long f(int y) throws Exception{ if(y==0)return 1; if(y==1)return x; long a; a=f(y/2); if(y%2==0) { return a*a%p; } return ((a*a)%p*x)%p; } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d018 子集合乘積(折半枚舉) 解法:折半枚舉、模逆元 ```Java= import java.io.*; import java.util.*; public class d018 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,p; public static long ans=0; public static void main(String[] args) throws Exception{ final int n=orz(); int begin=-1,q=0; long in; Integer query; long[] a=new long[(1<<(n/2))]; long[] b=new long[1<<(n-n/2)]; p=orz(); a[0]=b[0]=1; for(int i=0;i<n/2;i++) { in=orz(); for(int j=0;j<(1<<i);j++) { a[j+(1<<i)]=(a[j]*in)%p; } } a[0]=1<<30; Arrays.sort(a); HashMap<Integer,Integer> mp=new HashMap<>(); for(int i=0;i<a.length;i++) { if(a[i]==1)ans++; if(begin!=a[i]) { mp.put(begin,q); q=0; begin=(int)a[i]; } q++; q%=p; } for(int i=0;i<(n-n/2);i++) { in=orz(); for(int j=0;j<(1<<i);j++)b[j+(1<<i)]=(b[j]*in)%p; } for(int i=1;i<b.length;i++) { if(b[i]==1) { ans++; } query=mp.get(f((int)b[i],p-2)); if(query!=null) { ans+=query; ans%=p; } } System.out.println(ans); } public static int f(int x,int y) throws Exception{ if(y==0)return 1; if(y==1)return x; long a; a=f(x,y/2); if(y%2==0) { return (int)(a*a%p); } return (int)(((a*a)%p*x)%p); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d019 子集合的和(折半枚舉) 解法:折半枚舉、排序+二分搜 ```Java= import java.io.*; import java.util.*; public class d019 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static long ret,r; public static long ans=0; public static void main(String[] args) throws Exception{ final int n=(int)orz(); long p=orz(); long in; int l,r,mid=0; long[] a=new long[(1<<(n/2))]; long[] b=new long[(1<<(n-n/2))]; a[0]=b[0]=0; for(int i=0;i<n/2;i++) { in=orz(); for(int j=0;j<(1<<i);j++) { a[j+(1<<i)]=a[j]+in; } } a[0]=0; Arrays.sort(a); for(int i=0;i<(n-n/2);i++) { in=orz(); for(int j=0;j<(1<<i);j++) { b[j+(1<<i)]=b[j]+in; } } for(int i=0;i<b.length;i++) { l=0; r=a.length-1; while(l!=r) { mid=(l+r+1)/2; if(a[mid]+b[i]>p) { r=mid-1; } else { l=mid; } } if(a[l]+b[i]>p)continue; if(a[l]+b[i]>ans)ans=a[l]+b[i]; } System.out.println(ans); } public static long orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d020 最接近的區間和 解法:前綴和、二分搜 ```Java= import java.io.*; import java.util.*; public class d020 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static boolean neg; public static long sum=0,ans=0; public static void main(String[] args) throws Exception{ final int n=orz(); final int k=orz(); int bis; ArrayList<Long> al=new ArrayList<>(); al.add(0L); for(int i=0;i<n;i++) { sum+=orz(); bis=Collections.binarySearch(al,sum-k); if(bis<0)bis=bis*-1-1; if(bis<al.size()) { if(sum-al.get(bis)>ans)ans=sum-al.get(bis); } bis=Collections.binarySearch(al,sum); if(bis<0)bis=bis*-1-1; al.add(bis,sum); } System.out.println(ans); } public static int orz() throws Exception{ ret=0; r=br.read(); neg=false; if(r=='-') { neg=true; r=br.read(); } while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } if(neg)ret*=-1; return ret; } } ``` --- ## d021~d040 ### d021 unsolved 解法:這題會卡時間限制,所以下面的扣過不了,有主意可題 ```Java= import java.io.*; import java.util.*; public class d021 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static boolean neg; public static int sum=0,ans=0; public static int[][] presum; public static void main(String[] args) throws Exception{ orz(); final int k=ret; orz(); final int m=ret; orz(); final int n=ret; int bis; presum=new int[m+5][n+5]; for(int a=1;a<=m;a++) { for(int b=0;b<n;b++) { orz(); presum[a][b]=presum[a-1][b]+ret; } } ArrayList<Integer> al=new ArrayList<>(); for(int x=1;x<=m;x++) { for(int y=x;y<=m;y++) { sum=0; al.clear(); al.add(0); for(int i=0;i<n;i++) { sum+=(presum[y][i]-presum[x-1][i]); bis=Collections.binarySearch(al,sum-k); if(bis<0)bis=bis*-1-1; if(bis<al.size()) { if(sum-al.get(bis)>ans)ans=sum-al.get(bis); } bis=Collections.binarySearch(al,sum); if(bis<0)bis=bis*-1-1; al.add(bis,sum); } } } System.out.println(ans); } public static void orz() throws Exception{ ret=0; r=br.read(); neg=false; if(r=='-') { neg=true; r=br.read(); } while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } if(neg)ret*=-1; } } ``` --- ### d022 無理數的快速冪 解法:快速冪、數學 ```Java= import java.io.*; public class d022 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,x,y,n; public static final int p=(int)Math.pow(10,9)+9; public static boolean neg; public static void main(String[] args) throws Exception{ x=orz(); y=orz(); n=orz(); pair ans=f(n); System.out.println(ans.s+" "+ans.t); } public static pair f(int n) throws Exception{ if(n==0)return new pair(0,0); if(n==1)return new pair(x,y); pair a; a=f(n/2); if(n%2==0) { return multiply(a,a); } return multiply(multiply(a,a),new pair(x,y)); } public static pair multiply(pair a,pair b) { long ssum=(((a.t*b.t)*2)+a.s*b.s)%p; long tsum=(a.t*b.s+a.s*b.t)%p; return new pair(ssum,tsum); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } class pair{ long s,t; pair(long A,long B){ s=A; t=B; } } ``` --- ### d023 水槽 解法:遞迴 ```Java= import java.util.*; import java.io.*; public class d023 implements Runnable{ public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out)); public static int ret,r,idx,in; public static long retl,w; public static int[] wa=new int[100005]; public static partri[] H; public static void main(String[] args) throws Exception{ new Thread(null,new d023(),"",1<<26).start(); } public void run(){ String[] in2 = null; try { in2 = br.readLine().split(" "); } catch (IOException e1) { } final int n=Integer.parseInt(in2[0]); final int s=Integer.parseInt(in2[1]); w=Long.parseLong(in2[2]); in=s; try { in2=br.readLine().split(" "); } catch (IOException e1) { } H=new partri[n]; for(int i=0;i<n;i++)H[i]=new partri(i,Integer.parseInt(in2[i])); Arrays.sort(H,new Comparator<partri>() { public int compare(partri f,partri s) { return (int) (f.h-s.h); } }); idx=n; fill(0,n-1); for(int i=0;i<n-1;i++) { try { bw.write(wa[i]+" "); } catch (IOException e) { } } try { bw.flush(); } catch (IOException e) { } } static void fill(long l,long r) { if(l==r-1) { wa[(int) l]=(int) w; w=0; return; } else { idx--; while(idx>0&&H[idx].x<l||H[idx].x>r) { idx--; } if(w>=(r-l)*H[idx].h) { for(int i=(int) l;i<r;i++) { wa[i]=(int) (w/(r-l)); } w=0; return; } else if(H[idx].x>in) { if(w>=(H[idx].x-l)*H[idx].h) { for(int i=(int) l;i<H[idx].x;i++) { wa[i]=(int) H[idx].h; } w-=(H[idx].x-l)*H[idx].h; fill(H[idx].x,r); } else { fill(l,H[idx].x); } } else { if(w>=(r-H[idx].x)*H[idx].h) { for(int i=(int) H[idx].x;i<r;i++) { wa[i]=(int) H[idx].h; } w-=(r-H[idx].x)*H[idx].h; fill(l,H[idx].x); } else { fill(H[idx].x,r); } } } } } class partri{ long x,h; partri(int a,int b){ x=a; h=b; } } ``` --- ### d024 圓環出口 解法:前綴和、二分搜 ```Java= import java.util.*; import java.io.*; public class d024 { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String[] input=br.readLine().split(" "); int r = Integer.parseInt(input[0]); int m = Integer.parseInt(input[1]); //build sum int[] sum = new int[2*r]; int[] s = new int[2*r]; int[] mis = new int[m]; input=br.readLine().split(" "); for(int i=0;i<r;i++) { s[i]=Integer.parseInt(input[i]); s[i+r]=Integer.parseInt(input[i]); } input=br.readLine().split(" "); for(int i=0;i<m;i++) { mis[i]=Integer.parseInt(input[i]); } sum[0]=s[0]; for(int i=1;i<2*r;i++) { sum[i]=sum[i-1]+s[i]; } int cal,bis; int pos=0; for(int i=0;i<m;i++) { if(pos==0)cal=0; else cal=sum[pos-1]; cal+=mis[i]; bis=Arrays.binarySearch(sum,cal); if(bis<0)bis=-bis-1; pos=bis+1; pos%=r; } System.out.println(pos); } } ``` --- ### d025 樹的高度與根 解法:Bottom up ```Java= import java.io.*; public class d025 implements Runnable{ static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); static int r,ret; static int[] h=new int[100005]; static int[] fa=new int[100005]; static boolean[] lf=new boolean[100005]; public static void main(String[] args) throws Exception { new Thread(null, new d025(), "", 1<<26).start(); } public void run() { final int n=orz(); int num; for(int i=1;i<=n;i++) { num=orz(); if(num==0)lf[i]=true; for(int j=0;j<num;j++) { fa[orz()]=i; } } for(int i=1;i<=n;i++) { if(lf[i]) { bottom_up(fa[i],1); } } long ans=0,root=0; for(int i=1;i<=n;i++) { if(fa[i]==0)root=i; ans+=h[i]; } System.out.println(root); System.out.println(ans); } static void bottom_up(int x,int ht) { if(x==0)return; if(h[x]!=0) { if(ht>h[x]) { h[x]=ht; } else { return; } } else { h[x]=ht; } bottom_up(fa[x],ht+1); } static int orz() { try { ret=0; r=br.read(); while (r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } catch(Exception e) { return 0; } } } ``` --- ### d026 括弧配對 解法:牛排 ```Java= import java.io.*; import java.util.*; public class d026 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static boolean neg; public static void main(String[] args) throws Exception{ String in; Stack<Integer> st=new Stack<>(); all: while(true) { int r; in=br.readLine(); if(in==null||in.length()==0)break; st.clear(); for(int i=0;i<in.length();i++) { r=in.charAt(i); if(r=='(') { st.push(0); } if(r=='{') { st.push(1); } if(r=='[') { st.push(2); } if(r==')') { if(st.isEmpty()||st.pop()!=0) { System.out.println("no"); continue all; } } if(r=='}') { if(st.isEmpty()||st.pop()!=1) { System.out.println("no"); continue all; } } if(r==']') { if(st.isEmpty()||st.pop()!=2) { System.out.println("no"); continue all; } } } if(st.isEmpty()) { System.out.println("yes"); } else { System.out.println("no"); } } } } ``` --- ### d027 加減乘除 解法:Python_eval(這是別人的扣) ```Python= import sys for s in sys.stdin: s=s.replace('/',"//") print(int(eval(s))) ``` --- ### d028 最接近的高人 解法:二分搜、遞增序列維護 ```Java= import java.io.*; import java.util.*; public class d028 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int r,ret; public static void main(String[] args) throws Exception{ final int n=orz(); int l,r,mid,t; long ans=0; ArrayList<pii> al=new ArrayList<>(); al.add(new pii(-(1<<30),-1)); al.add(new pii((1<<30),-1)); for(int i=0;i<n;i++) { t=orz(); l=0; r=al.size()-1; while(l!=r) { mid=(l+r)/2; if(al.get(mid).h>t) { r=mid; } else { l=mid+1; } } ans+=(i-al.get(l).id); al.add(l,new pii(t,i)); l--; while(l>=0&&al.get(l).h<=t) { al.remove(l); l--; } } System.out.println(ans); } public static int orz() throws Exception{ ret=0; r=br.read(); if(r=='-') { r=br.read(); } while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } class pii{ int h,id; pii(int a,int b){ h=a; id=b; } } ``` --- ### d029 帶著板凳排雞排的高人 解法:二分搜、遞增序列維護 ```Java= import java.io.*; import java.util.*; public class d029 { public static int ret,r; public static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); public static void main(String[] args) throws Exception { final int n=readint(); ArrayList<pair> v=new ArrayList<>(); int[] h=new int[n]; int l,r,m=0,t; long rt=0; for(int i=0;i<n;i++) { h[i]=readint(); } v.add(new pair(0,1<<30)); v.add(new pair(0,-(1<<30))); for(int i=1;i<=n;i++) { t=readint()+h[i-1]; l=0; r=v.size()-1; while(l!=r) { m=(l+r)/2; if(v.get(m).h>t) { l=m+1; } else { r=m; } } rt+=i-(v.get(l-1).id+1); for(int j=v.size()-2;j>-1;j--) { if(v.get(j).h<=h[i-1]) { v.remove(j); } else{ v.add(v.size()-1,new pair(i,h[i-1])); break; } } } System.out.println(rt); } public static int readint() throws Exception { ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } class pair{ int id,h; pair(int a,int b){ id=a; h=b; } } ``` --- ### d030 砍樹 解法:ArrayList ```Java= import java.io.*; import java.util.*; public class d030 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,mx,ans=0; public static int[] idx=new int[100005]; public static int[] h=new int[100005]; public static void main(String[] args) throws Exception{ final int n=orz(); final int l=orz(); ArrayList<tree> al=new ArrayList<>(); al.add(new tree(0,1<<30)); for(int i=0;i<n;i++)idx[i]=orz(); for(int i=0;i<n;i++)h[i]=orz(); for(int i=0;i<n;i++)al.add(new tree(idx[i],h[i])); al.add(new tree(l,1<<30)); for(int i=0;i<al.size()-1;i++) { if(i==0)continue; if(al.get(i).x-al.get(i).h>=al.get(i-1).x) { mx=Math.max(mx,al.get(i).h); al.remove(i); i-=2; ans++; } else if(al.get(i).x+al.get(i).h<=al.get(i+1).x){ mx=Math.max(mx,al.get(i).h); al.remove(i); i-=2; ans++; } } System.out.println(ans); System.out.println(mx); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } class tree{ int x,h; tree(int a,int b){ x=a; h=b; } } ``` --- ### d031 正整數序列之最接近的區間和 解法:Sliding Window ```Java= import java.io.*; import java.util.*; public class d031 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,ans=0; public static long max=0; public static void main(String[] args) throws Exception{ long sum=0; int l=0; final int n=orz(); final int k=orz(); int[] a=new int[n]; for(int i=0;i<n;i++)a[i]=orz(); for(int i=0;i<n;i++) { sum+=a[i]; while(sum>k) { sum-=a[l++]; } if(sum>max) { max=sum; ans=1; } else if(sum==max)ans++; } System.out.println(max); System.out.println(ans); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d032 固定長度區間的最大區段差 解法:ArrayList(串列) ```Java= import java.io.*; import java.util.*; public class d032 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,rd,mx=0,l,r,m; public static ArrayList<P> a=new ArrayList<>(); public static void main(String[] args) throws Exception{ final int n=orz(); final int L=orz(); int[] in=new int[n]; for(int i=0;i<n;i++)in[i]=orz(); for(int i=0;i<L-1;i++) { a.add(bis(in[i]),new P(i,in[i])); } for(int i=0,j=L-1;j<n;i++,j++) { a.add(bis(in[j]),new P(j,in[j])); while(a.get(0).idx<i)a.remove(0); while(a.get(a.size()-1).idx<i)a.remove(a.size()-1); mx=Math.max(a.get(a.size()-1).val-a.get(0).val,mx); } System.out.println(mx); } public static int bis(int x) { l=0; r=a.size(); while(l!=r) { m=(l+r)/2; if(a.get(m).val<=x) { l=m+1; } else { r=m; } } return l; } public static int orz() throws Exception{ ret=0; rd=br.read(); while(rd>47&&rd<58) { ret*=10; ret+=(rd&15); rd=br.read(); } return ret; } } class P{ int idx,val; P(int a,int b){ idx=a; val=b; } } ``` --- ### d033 最多色彩帶 解法:雙指標 ```Java= import java.io.*; import java.util.*; public class d033 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,rd,mx=0,cc=0; public static int[] col=new int[200005]; public static void main(String[] args) throws Exception{ final int n=orz(); final int L=orz(); int[] in=new int[n]; for(int i=0;i<n;i++)in[i]=orz(); for(int j=0;j<L-1;j++) { if(col[in[j]]==0)cc++; col[in[j]]++; } for(int i=0,j=L-1;j<n;i++,j++) { if(col[in[j]]==0)cc++; col[in[j]]++; if(mx<cc)mx=cc; col[in[i]]--; if(col[in[i]]==0)cc--; } System.out.println(mx); } public static int orz() throws Exception{ ret=0; rd=br.read(); while(rd>47&&rd<58) { ret*=10; ret+=(rd&15); rd=br.read(); } return ret; } } ``` --- ### d034 全彩彩帶 解法:雙指標 ```Java= import java.io.*; import java.util.*; public class d034 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,rd,idx=0,min; public static int[] col=new int[200005]; public static void main(String[] args) throws Exception{ final int n=orz(); HashMap<Integer,Integer> mp=new HashMap<>(); int[] in=new int[n]; for(int i=0;i<n;i++) { in[i]=orz(); if(mp.get(in[i])==null)mp.put(in[i],idx++); } int cc=0,l=0,r=-1,g; while(cc<idx) { g=mp.get(in[++r]); if(col[g]==0)cc++; col[g]++; } min=r-l+1; for(;r<n;r++) { col[mp.get(in[r])]++; while(col[mp.get(in[l])]>1) { col[mp.get(in[l])]--; l++; } if(r-l+1<min)min=r-l+1; } System.out.println(min); } public static int orz() throws Exception{ ret=0; rd=br.read(); while(rd>47&&rd<58) { ret*=10; ret+=(rd&15); rd=br.read(); } return ret; } } ``` --- ### d035 最長的相異色彩帶 解法:雙指標 ```Java= import java.io.*; import java.util.*; public class d035 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,rd,idx=0,mx=0; public static int[] col=new int[200005]; public static int[] last=new int[200005]; public static void main(String[] args) throws Exception{ final int n=orz(); Arrays.fill(last,-1); int l=0,read; for(int i=0;i<n;i++) { read=orz(); if(last[read]!=-1)l=Math.max(l,last[read]+1); last[read]=i; mx=Math.max(mx,i-l+1); } System.out.println(mx); } public static int orz() throws Exception{ ret=0; rd=br.read(); while(rd>47&&rd<58) { ret*=10; ret+=(rd&15); rd=br.read(); } return ret; } } ``` --- ### d036 完美彩帶 解法:雙指標 ```Java= import java.io.*; import java.util.*; public class d036 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,rd,ans=0,idx=0; public static int[] last=new int[200005]; public static void main(String[] args) throws Exception{ final int m=orz(); final int n=orz(); Arrays.fill(last,-1); HashMap<Integer,Integer> mp=new HashMap<>(); int l=0,read; for(int i=0;i<n;i++) { read=orz(); if(mp.get(read)==null)mp.put(read,idx++); read=mp.get(read); if(last[read]!=-1)l=Math.max(l,last[read]+1); last[read]=i; if(i-l+1==m)ans++; } System.out.println(ans); } public static int orz() throws Exception{ ret=0; rd=br.read(); while(rd>47&&rd<58) { ret*=10; ret+=(rd&15); rd=br.read(); } return ret; } } ``` --- ### d037 X差值範圍內的最大Y差值 解法:ArrayList、二分搜 ```Java= import java.io.*; import java.util.*; public class d037 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,rd,mx=0,l,r,m; public static boolean neg; public static ArrayList<P> a=new ArrayList<>(); public static void main(String[] args) throws Exception{ final int n=orz(); final int L=orz(); int[] x=new int[n]; int[] y=new int[n]; P[] in=new P[n]; for(int i=0;i<n;i++)x[i]=orz(); for(int i=0;i<n;i++)y[i]=orz(); for(int i=0;i<n;i++) { in[i]=new P(x[i],y[i]); } Arrays.sort(in,new Comparator<P>() { public int compare(P f,P s) { return f.idx-s.idx; } }); for(int i=0;i<n;i++) { a.add(bis(in[i].val),in[i]); while(a.get(0).idx<in[i].idx-L)a.remove(0); while(a.get(a.size()-1).idx<in[i].idx-L)a.remove(a.size()-1); mx=Math.max(a.get(a.size()-1).val-a.get(0).val,mx); } System.out.println(mx); } public static int bis(int x) { l=0; r=a.size(); while(l!=r) { m=(l+r)/2; if(a.get(m).val<=x) { l=m+1; } else { r=m; } } return l; } public static int orz() throws Exception{ neg=false; ret=0; rd=br.read(); if(rd=='-') { neg=true; rd=br.read(); } while(rd>47&&rd<58) { ret*=10; ret+=(rd&15); rd=br.read(); } if(neg)ret*=-1; return ret; } } class P{ int idx,val; P(int a,int b){ idx=a; val=b; } } ``` --- ### d038 unsolved 解法: ```Java= ``` --- ## d041~d060 ### d042 少林寺的代幣 解法:Greedy ```Java= import java.io.*; import java.util.*; public class d042 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out)); public static int ret,r,rr; public static void main(String[] args) throws Exception{ final int t=orz(); for(int i=0;i<t;i++) { rr=orz(); bw.write((rr/50+rr%50/10+rr%10/5+rr%5)+"\n"); } bw.flush(); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d043 笑傲江湖之三戰 解法:Greedy ```Java= import java.io.*; import java.util.*; public class d043 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,cnt=0; public static void main(String[] args) throws Exception{ final int n=orz(); int[] m=new int[n]; int[] o=new int[n]; for(int i=0;i<n;i++)o[i]=orz(); for(int i=0;i<n;i++)m[i]=orz(); Arrays.sort(m); Arrays.sort(o); for(int i=0;i<n;i++) { if(m[i]>o[cnt])cnt++; } System.out.println(cnt); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d044 十年磨一劍 解法:Greedy ```Java= import java.io.*; import java.util.*; public class d044 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static long cnt=0,presum=0; public static void main(String[] args) throws Exception{ final int n=orz(); int[] a=new int[n]; for(int i=0;i<n;i++)a[i]=orz(); Arrays.sort(a); for(int i=0;i<n;i++) { presum+=a[i]; cnt+=presum; } System.out.println(cnt); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d045 幾場華山論劍 解法:Greedy ```Java= import java.io.*; import java.util.*; public class d045 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,cnt,cr=-1; public static void main(String[] args) throws Exception{ final int n=orz(); pair[] a=new pair[n]; for(int i=0;i<n;i++) { a[i]=new pair(orz(),orz()); } Arrays.sort(a,new Comparator<pair>() { public int compare(pair f,pair s) { return (f.r-s.r==0)?(f.l-s.l):(f.r-s.r); } }); for(int i=0;i<n;i++) { if(cr<a[i].l) { cnt++; cr=a[i].r; } } System.out.println(cnt); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } class pair{ int l,r; pair(int x,int y){ l=x; r=y; } } ``` --- ### d046 嵩山磨劍坊的問題 解法:sort ```Java= import java.io.*; import java.util.*; public class d046 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static long t=0,sum=0; public static void main(String[] args) throws Exception{ final int n=orz(); pair[] p=new pair[n]; for(int i=0;i<n;i++) p[i]=new pair(orz()); for(int i=0;i<n;i++) p[i].wei(orz()); Arrays.sort(p,new Comparator<pair>(){ public int compare(pair f,pair s) { return f.t*s.w-f.w*s.t; } }); for(int i=0;i<n;i++) { t+=p[i].t; sum+=p[i].w*t; } System.out.println(sum); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } class pair{ int t,w; pair(int x){ t=x; } void wei(int y){ w=y; } } ``` --- ### d047 少林寺的自動寄物櫃 解法:sort(d046改) ```Java= import java.io.*; import java.util.*; public class d047 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static long t=0,sum=0; public static void main(String[] args) throws Exception{ final int n=orz(); pair[] p=new pair[n]; for(int i=0;i<n;i++) p[i]=new pair(orz()); for(int i=0;i<n;i++) p[i].wei(orz()); Arrays.sort(p,new Comparator<pair>(){ public int compare(pair f,pair s) { return f.t*s.w-f.w*s.t; } }); for(int i=0;i<n;i++) { sum+=p[i].w*t; t+=p[i].t; } System.out.println(sum); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } class pair{ int t,w; pair(int x){ t=x; } void wei(int y){ w=y; } } ``` --- ### d048 岳不群的併派問題 解法:博愛排隊(Priority-Queue) ```Java= import java.io.*; import java.util.*; public class d048 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static long sum=0,cost=0; public static void main(String[] args) throws Exception{ final int n=orz(); long a,b; PriorityQueue<Long> pq=new PriorityQueue<>(new Comparator<Long>(){ public int compare(Long a,Long b) { if(a>b)return 1; else if(a==b)return 0; return -1; } }); for(int i=0;i<n;i++) { a=orz(); sum+=a; pq.offer(a); } while(pq.size()!=1) { a=pq.poll(); b=pq.poll(); cost+=(a+b); pq.offer(a+b); } System.out.println(sum); System.out.println(cost); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d049 基地台 解法:二分搜 ```Java= import java.util.*; import java.io.*; public class d049 { public static int[] data; public static int k; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String[] input=br.readLine().split(" "); int n=Integer.parseInt(input[0]); k=Integer.parseInt(input[1]); input=br.readLine().split(" "); data=new int[n]; for(int i=0;i<n;i++) data[i]=Integer.parseInt(input[i]); Arrays.sort(data); int min=1; int max=1000000000; int mid; while(min<max) { mid=(min+max)/2; if(bis(mid)) max=mid; else min=mid+1; } System.out.println(max); } public static boolean bis(int x) { int range=0; int kkkk=0; for(int i=0;i<data.length;i++) { if(data[i]>range) { range=data[i]+x; kkkk++; } if(kkkk>k)return false; } return true; } } ``` --- ### d050 線段覆蓋長度 解法:sort ```Java= import java.io.*; import java.util.*; public class d050 { public static int r; public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static void main(String[] args) throws Exception{ final int t=readint(); int[][] l=new int[t][2]; for(int i=0;i<t;i++) { l[i][0]=readint(); l[i][1]=readint(); } Arrays.sort(l,new Comparator<int[]>() { public int compare(int[] f,int[] s){ if(f[0]>s[0])return 1; else { return -1; } } }); int cs=-1; int ce=-2; int e; int out=0; for(int i=0;i<t;i++) { if(l[i][0]>ce+1) { out+=ce-cs+1; cs=l[i][0]; } e=l[i][1]-1; ce=(e>ce)?e:ce; } System.out.println(out+ce-cs+1); } public static int readint() throws Exception { int add=0; while(true) { r=br.read(); if(r<47||r>58) { return add; } else { r=r&15; add*=10; add+=r; } } } } ``` --- ### d051 一次買賣 解法:greedy ```Java= import java.io.*; import java.util.*; public class d051 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static long ans=0,min=(1<<30); public static void main(String[] args) throws Exception{ final int n=orz(); int a; for(int i=0;i<n;i++) { a=orz(); if(a-min>ans)ans=a-min; if(min>a)min=a; } System.out.println(ans); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d052 最大連續子陣列 解法:DP(低批) ```Java= import java.io.*; import java.util.*; public class d052 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static long ans=0; public static boolean neg; public static long[] sum=new long[100005]; public static void main(String[] args) throws Exception{ final int n=orz(); int a; sum[0]=orz(); for(int i=1;i<n;i++) { a=orz(); if(sum[i-1]>0) { sum[i]=sum[i-1]+a; } else { sum[i]=a; } if(sum[i]>ans)ans=sum[i]; } System.out.println(ans); } public static int orz() throws Exception{ ret=0; r=br.read(); neg=false; if(r=='-') { neg=true; r=br.read(); } while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } if(neg)ret*=-1; return ret; } } ``` --- ### d053 先到先服務 解法:greedy、Priority-Queue ```java= import java.io.*; import java.util.*; public class d053 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static void main(String[] args) throws Exception{ final int n=orz(); final int m=orz(); int ans=0; PriorityQueue<Integer> pq=new PriorityQueue<>(new Comparator<Integer>(){ public int compare(Integer a,Integer b) { return a-b; } }); for(int i=0;i<m;i++) pq.offer(0); for(int i=0;i<n;i++) { pq.offer(pq.poll()+orz()); } while(!pq.isEmpty())ans=pq.poll(); System.out.println(ans); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d054 恢復能量的白雲熊膽丸 解法:二分搜 ```java= import java.io.*; import java.util.*; public class d054 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static void main(String[] args) throws Exception{ final int n=orz(); final int m=orz(); int[] mp=new int[n+1]; int mx=0; for(int i=0;i<n;i++) { mp[i]=orz(); mx=Math.max(mx,mp[i]); } mp[n]=0; int l=mx,r=(int) Math.pow(10,9),mid,cp,c; boolean pass=true; while(l!=r) { pass=true; mid=(l+r)/2; cp=mid; c=m; for(int i=0;i<n;i++) { cp-=mp[i]; if(cp-mp[i+1]<0) { cp=mid; c--; if(c<0) { pass=false; break; } } } if(pass) { r=mid; } else{ l=mid+1; } } System.out.println(l); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d055 控制點 解法:sort、greedy ```Java= import java.io.*; import java.util.*; public class d055 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static void main(String[] args) throws Exception{ final int n=orz(); int[][] xy=new int[n][2]; for(int i=0;i<2;i++) { for(int j=0;j<n;j++) { xy[j][i]=orz(); } } Arrays.sort(xy,new Comparator<int[]>() { public int compare(int[] f,int[] s) { return (f[0]==s[0])?f[1]-s[1]:f[0]-s[0]; } }); int maxy=0,cnt=0; for(int i=n-1;i>=0;i--) { if(xy[i][1]>maxy) { maxy=xy[i][1]; cnt++; } } System.out.println(cnt); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d056 最靠近的一對 解法:排序、二分搜 ```Java= import java.io.*; import java.util.*; public class d056 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static boolean neg; public static void main(String[] args) throws Exception{ final int n=orz(); int best=1<<30,l,r,m,lo,hi,dx=0,dy=0; dot[] in=new dot[n]; for(int i=0;i<n;i++) { in[i]=new dot(orz(),orz()); } Arrays.sort(in,new Comparator<dot>(){ public int compare(dot f,dot s) { if(f.x==s.x)return f.y-s.y; return f.x-s.x; } }); ArrayList<dot> a=new ArrayList<>(); for(int i=0;i<n;i++) { lo=in[i].y-best; hi=in[i].y+best; l=0; r=a.size()-1; while(l<r) { m=(l+r)/2; if(a.get(m).y<lo) { l=m+1; } else { r=m; } } //if(l!=0)l--; for(int j=l;j<a.size();j++) { if(a.get(j).x<in[i].x-best) { a.remove(j--); } else { dx=Math.abs(a.get(j).x-in[i].x); dy=Math.abs(a.get(j).y-in[i].y); if(dx+dy<best)best=dx+dy; if(a.get(j).y>hi)break; } } l=0; r=a.size()-1; while(l<r) { m=(l+r)/2; if(a.get(m).y<=in[i].y) { l=m+1; } else { r=m; } } a.add(l,new dot(in[i].x,in[i].y)); } System.out.println(best); } public static int orz() throws Exception{ ret=0; r=br.read(); neg=false; if(r=='-') { neg=true; r=br.read(); } while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } if(neg)ret*=-1; return ret; } } class dot{ int x,y; dot(int a,int b){ x=a; y=b; } } ``` --- ### d057 賺錢與罰款 解法:greedy ```Java= import java.io.*; import java.util.*; public class d057 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static long time=0,sum=0; public static void main(String[] args) throws Exception{ final int n=orz(); int[] t=new int[n]; for(int i=0;i<n;i++)t[i]=orz(); for(int i=0;i<n;i++)sum+=orz(); Arrays.sort(t); for(int i=0;i<n;i++) { time+=t[i]; sum-=time; } System.out.println(sum); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d058 死線高手 解法:greedy ```Java= import java.io.*; import java.util.*; public class d058 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static long time=0; public static boolean penalty=false; public static void main(String[] args) throws Exception{ final int t=orz(); for(int a=0;a<t;a++) { penalty=false; int n=orz(); int[][] w=new int[n][2]; for(int i=0;i<n;i++) { w[i][0]=orz(); } for(int i=0;i<n;i++) { w[i][1]=orz(); } Arrays.sort(w,new Comparator<int[]>() { public int compare(int[] f,int[] s) { return f[1]-s[1]; } }); time=0; for(int i=0;i<n;i++) { time+=w[i][0]; if(w[i][1]<time) { penalty=true; break; } } System.out.println((penalty)?"no":"yes"); } } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d059 少林寺的櫃姐 解法:greedy、博愛排隊、二分搜 ```Java= import java.io.*; import java.util.*; public class d059 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r; public static void main(String[] args) throws Exception{ final int n=orz(); final int m=orz(); int l=1; int r=100000;//max ans int mid,ans=0; int[] t=new int[n]; PriorityQueue<Integer> pq=new PriorityQueue<>(new Comparator<Integer>(){ public int compare(Integer a,Integer b) { return a-b; } }); for(int i=0;i<n;i++) { t[i]=orz(); } while(l!=r) { mid=(l+r)/2; for(int i=0;i<mid;i++)pq.offer(0); for(int i=0;i<n;i++) { pq.offer(pq.poll()+t[i]); } while(!pq.isEmpty())ans=pq.poll(); if(ans>m)l=mid+1; else { r=mid; } } System.out.println(l); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } ``` --- ### d060 五嶽盟主的會議場所 解法:sliding window、博愛排隊 ```Java= import java.io.*; import java.util.*; public class d060 { public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); public static int ret,r,idx=0,cnt=0,max=0; public static void main(String[] args) throws Exception{ final int n=orz(); seg[] s=new seg[n]; seg p; for(int i=0;i<n;i++) s[i]=new seg(orz(),orz(),orz()); Arrays.sort(s,new Comparator<seg>() { public int compare(seg f,seg s) { return f.l-s.l; } }); PriorityQueue<seg> pq=new PriorityQueue<>(new Comparator<seg>() { public int compare(seg f,seg s) { return f.r-s.r; } }); for(int i=0;i<n;i++) { while(!pq.isEmpty()) { p=pq.poll(); if(p.r>=s[i].l) { pq.offer(p); break; } else { cnt-=p.v; } } pq.offer(s[i]); cnt+=s[i].v; max=Math.max(max,cnt); } System.out.println(max); } public static int orz() throws Exception{ ret=0; r=br.read(); while(r>47&&r<58) { ret*=10; ret+=(r&15); r=br.read(); } return ret; } } class seg{ int v,l,r; seg(int a,int b,int c){ v=a; l=b; r=c; } } ``` ---