NC50473. 跳跳棋
描述
输入描述
第一行包含三个整数,表示当前棋子的位置a,b,c。第二行包含三个整数,表示目标位置x,y,z。
输出描述
如果无解,输出一行NO。如果可以到达,第一行输出YES,第二行输出最少步数。
示例1
输入:
1 2 3 0 3 5
输出:
YES 2
Java 解法, 执行用时: 12ms, 内存消耗: 9460K, 提交时间: 2021-09-05 15:40:42
import java.io.*; import java.math.BigDecimal; import java.math.BigInteger; import java.math.RoundingMode; import java.text.DecimalFormat; import java.util.*; public class Main { static long mod = 1; static class SegmentTree { static int l; static int r; static long v; static Node root; static long cache[]; static void build(long f[]) { cache = f; root = new Node(0, f.length - 1); } static long query(int left, int right) { l = left; r = right; return root.query(); } static void add_range(int left, int right, long value) { l = left; r = right; v = value; root.add_range(); } static void multi_range(int left, int right, long value) { l = left; r = right; v = value; root.multi_range(); } static void set_range(int left, int right) { l = left; r = right; // root.set_range(); } static class Node { // boolean seted; long setv = 1; long add = 0; int left; int right; long min_value; Node l_node; Node r_node; public Node(int l, int r) { left = l; right = r; if (l == r) { min_value = cache[l]; } else { int mid = (l + r) >> 1; l_node = new Node(l, mid); r_node = new Node(mid + 1, r); pollup(); } } private long query() { if (l <= left && r >= right) { return min_value; } else if (l > right || r < left) { return 0; } else { pushdown(); long v1 = l_node.query(); long v2 = r_node.query(); pollup(); return (v1 + v2) % mod; } } private void add_range() { if (l <= left && r >= right) { add += v; min_value += v * (right - left + 1); } else if (l > right || r < left) { return; } else { pushdown(); l_node.add_range(); r_node.add_range(); pollup(); } } private void multi_range() { if (l <= left && r >= right) { setv *= v; add = add * v; min_value = (min_value * v) % mod; } else if (l > right || r < left) { return; } else { pushdown(); l_node.multi_range(); r_node.multi_range(); pollup(); } } // private void set_range() { // if (l <= left && r >= right) { // seted = true; // setv = v; // add = 0; // min_value = v; // } else if (l > right || r < left) { // return; // } else { // pushdown(); // l_node.set_range(); // r_node.set_range(); // pollup(); // } // } // first multi, then add private void pushdown() { if (setv != 1) { l_node.setv *= setv; r_node.setv *= setv; l_node.min_value = l_node.min_value * setv % mod; r_node.min_value = r_node.min_value * setv % mod; l_node.add = l_node.add * setv; r_node.add = r_node.add * setv; setv = 1; } if (add != 0) { l_node.add += add; r_node.add += add; l_node.min_value += add * (l_node.right - l_node.left + 1); l_node.min_value %= mod; r_node.min_value += add * (r_node.right - r_node.left + 1); r_node.min_value %= mod; add = 0; } } private void pollup() { min_value = (l_node.min_value + r_node.min_value) % mod; } } } static class Task { public static String roundS(double result, int scale) { String fmt = String.format("%%.%df", scale); return String.format(fmt, result); // DecimalFormat df = new DecimalFormat("0.000000"); // double result = Double.parseDouble(df.format(result)); } long[][] mult(long a[][], long b[][], long mod) { int l1 = a.length; int l2 = b.length; int l3 = b[0].length; long r[][] = new long[l1][l3]; for (int i = 0; i < l1; ++i) { for (int j = 0; j < l2; ++j) { for (int k = 0; k < l3; ++k) { r[i][k] = (r[i][k] + a[i][j] * b[j][k] % mod) % mod; } } } return r; } long[][] add(long a[][], long b[][], long mod) { int l1 = a.length; int l2 = a[0].length; long r[][] = new long[l1][l2]; for (int i = 0; i < l1; ++i) { for (int j = 0; j < l2; ++j) { r[i][j] = (a[i][j] + b[i][j]) % mod; } } return r; } long[][] ones(int len) { long r[][] = new long[len][len]; for (int i = 0; i < len; ++i) { r[i][i] = 1L; } return r; } long[][] quick(long a[][], int times, long mod) { int len = a.length; long ans[][] = ones(len); while (times > 0) { if ((times & 1) == 1) { ans = mult(ans, a, mod); } a = mult(a, a, mod); times >>= 1; } return ans; } long mb = 1535002967L; long p = 1331; long hash[]; long f[]; long getHash(int i, int l) { // str from i to (i+len-1) return (mb + (hash[i + l] - f[l] * hash[i]) % mb) % mb; } void hash(String s) { int len = s.length(); hash = new long[len + 1]; f = new long[len + 1]; hash = new long[len + 1]; f[0] = 1; for (int j = 1; j <= len; ++j) { hash[j] = (hash[j - 1] * p + s.charAt(j - 1)) % mb; f[j] = (f[j - 1] * p) % mb; } // for(int i=0;i<len;++i){ // for(int l = 0;i+l<=len;++l){ // long v = getHash(i,l); // } // } } void dfs(int rt) { int[] stk = new int[n]; int e = 1; while (0<e) { int cur = stk[--e]; for (int to[] : g[cur]) { if (to[1] != fa[cur][0]) { fa[to[1]][0] = cur; dep[to[1]] = dep[cur] + 1; wt[to[1]][0] = to[0]; stk[e++] = to[1]; } } } for (int j = 1; j <= 17; ++j) { for (int p = 0; p < n; ++p) { fa[p][j] = fa[fa[p][j - 1]][j - 1]; wt[p][j] = Math.max(wt[fa[p][j - 1]][j - 1], wt[p][j-1]); long sc = Math.max(swt[fa[p][j - 1]][j - 1], swt[p][j-1]); if(wt[fa[p][j - 1]][j - 1]!= wt[p][j-1]){ swt[p][j] = Math.max(sc,wt[fa[p][j - 1]][j - 1] + wt[p][j-1] -wt[p][j]); }else{ swt[p][j] = sc; } } } } int fa[][]; List<int[]> g[]; int n; int dep[]; long wt[][]; long swt[][]; long mx = 0,smx = 0; void lca(int a, int b) { if (dep[a] > dep[b]) { int u = a; a = b; b = u; } // dep a <= dep b int dis = dep[b] - dep[a]; for (int i = 0; i <= 17; ++i) { if (dis << ~i < 0) { if(wt[b][i]>=mx){ smx = Math.max(mx,swt[b][i]); mx = wt[b][i]; }else if(wt[b][i]>smx){ smx = wt[b][i]; } b = fa[b][i]; } } if (a == b) return ; for (int i = 17; i >= 0; --i) { if (fa[b][i] != fa[a][i]) { if(wt[b][i]>=mx){ smx = Math.max(mx,swt[b][i]); mx = wt[b][i]; }else if(wt[b][i]>smx){ smx = wt[b][i]; } b = fa[b][i]; if(wt[a][i]>=mx){ smx = Math.max(mx,swt[a][i]); mx = wt[a][i]; }else if(wt[a][i]>smx){ smx = wt[a][i]; } a = fa[a][i]; } } if(wt[a][0]>=mx){ smx = Math.max(mx,swt[a][0]); mx = wt[a][0]; }else if(wt[a][0]>smx){ smx = wt[a][0]; } if(wt[b][0]>=mx){ smx = Math.max(mx,swt[b][0]); mx = wt[b][0]; }else if(wt[b][0]>smx){ smx = wt[b][0]; } return ; } int fat[]; int rt(int u){ if(u!=fat[u]){ return fat[u] = rt(fat[u]); } return u; } void mrg(int u,int v){ int u1 = fat[u]; int u2 = fat[v]; fat[u1] = u2; } int ct = 0; long[] g(long a[],long limit){ if(limit==0){ return a; } long b[] = new long[3]; if(a[1]-a[0]<a[2]-a[1]){ long d1 = a[1] - a[0]; long d2 = a[2] - a[1] - 1; long num = Math.min(limit,d2/d1); limit -= num; ct += num; b[1] = a[1] + num*d1; b[0] = b[1] - d1; b[2] = a[2]; return g( b, limit); }else if(a[2]-a[1]<a[1]-a[0]){ long d1 = a[2] - a[1]; long d2 = a[1] - a[0] - 1; long num = Math.min(limit,d2/d1); limit -= num; ct += num; b[1] = a[1] - num*d1; b[2] = b[1] + d1; b[0] = a[0]; return g( b, limit); }else{ return a; } } public void solve(int testNumber, InputReader in, PrintWriter out) { long a[] = new long[3]; long b[] = new long[3]; for(int i=0;i<3;++i){ a[i] = in.nextLong(); } for(int i=0;i<3;++i){ b[i] = in.nextLong(); } Arrays.sort(a); Arrays.sort(b); ct = 0; long r1[] = g(a,Long.MAX_VALUE); long ct1 = ct; ct = 0; long r2[] = g(b,Long.MAX_VALUE); long ct2 = ct; if(ct1<ct2){ long t[] = a.clone(); a = b; b = t; long v = ct1; ct1 = ct2; ct2 = v; } long dis = ct1-ct2; long cur[] = g(a,dis); a = cur; if(Arrays.equals(r1,r2)){ out.println("YES"); long lo = 0; long hi = ct1 + ct2; while(lo<hi){ long mid = (lo+hi)/2; ct= 0; r1 = g(a,mid); ct = 0; r2 = g(b,mid); if(Arrays.equals(r1,r2)){ hi = mid; }else{ lo = mid+1; } } out.println(lo*2+(dis)); }else{ out.print("NO"); } } // int t = in.nextInt(); // int n = in.nextInt(); // int m = in.nextInt(); // // ct = 0; // h = new int[n];Arrays.fill(h,-1); // if(t==1) { // to = new int[m * 2]; // ne = new int[m * 2]; // // fob = new boolean[m * 2]; // }else{ // to = new int[m]; // ne = new int[m]; // // } // // // int rd[] = new int[n]; // int cd[] = new int[n]; // li = new int[m]; // tp = m-1; // // int rt= 0; // // for(int i=0;i<m;++i){ // int u = in.nextInt()-1; // int v = in.nextInt()-1; // add(u,v); // if(t==1){ // add(v,u); // } // cd[u]++; // rd[v]++; // rt = u; // } // // if(t==2){ // // for(int i=0;i<n;++i){ // if(rd[i]!=cd[i]){ // out.println("NO");return; // } // } // }else{ // // for(int i=0;i<n;++i){ // if(((rd[i]+cd[i])%2)>0){ // out.println("NO");return; // } // } // // } // // // // dfs11(rt, t); // // // // if(tp!=-1){ // out.print("NO"); // return; // } // // out.println("YES"); // // for(int i=0;i<m;++i){ // out.print(li[i]+ " "); // } // int f1[][] = new int[q][3]; // // for(int i=0;i<q;++i){ // for(int j=0;j<3;++j){ // f1[i][j] = in.nextInt(); // } // } // // // int h[] = new int[n+1]; // // Arrays.fill(h,-1); // // // int ne[] = new int[p*2+q]; // int to[] = new int[p*2+q]; // int wt[] = new int[p*2+q]; // ct = 0; // Func fk = (int x,int y,int z) -> { // to[ct] = y; // ne[ct] = h[x]; // wt[ct] = z; // h[x] = ct++; // }; // // for(int i=0;i<p;++i){ // int u = f[i][0]; // int v = f[i][1]; // // // // // fk.add(u,v,f[i][2]); // fk.add(v,u,f[i][2]); // } // // for(int i=0;i<q;++i){ // int u = f1[i][0]; // int v = f1[i][1]; // // // // // fk.add(u,v,f1[i][2]); // } // int dp[] = new int[n+1]; // Arrays.fill(dp,100000000); // dp[s] = 0; // // // PriorityQueue<int[]> qu = new PriorityQueue<>(Comparator.comparingInt((x)->x[0])); // qu.add(new int[]{0,s}); // while(qu.size()>0){ // int cc[] = qu.poll(); // int cur = cc[1]; // if(cc[0]!=dp[cur]) continue; // for(int j = h[cur];j!=-1;j=ne[j]){ // int v = to[j]; // if(dp[v] > dp[cur] + wt[j]){ // dp[v] = dp[cur] + wt[j]; // qu.offer(new int[]{dp[v],v}); // } // } // } // // for(int j=1;j<=n;++j){ // if(dp[j]==100000000){ // out.println("NO PATH"); // }else{ // out.println(dp[j]); // } // } // for(int t=0;t<5;++t) { // int at = fi[t]; // dp[at][t] = 0; // PriorityQueue<int[]> q = new PriorityQueue<>(Comparator.comparingInt((x) -> x[0])); // q.offer(new int[]{0, at}); // while (q.size() > 0) { // int cur[] = q.poll(); // if (cur[0] != dp[cur[1]][t]) continue; // int i = cur[1]; // for (int j = h[i]; j != -1; j = ne[j]) { // int v = to[j]; // if (dp[i][t] + wt[j] < dp[v][t]) { // dp[v][t] = dp[i][t] + wt[j]; // q.offer(new int[]{dp[v][t], v}); // } // } // } // } // int cl[] = new int[]{0,1,2,3,4}; // int rs = Integer.MAX_VALUE; // do{ // int s= dp[1][cl[0]]; // for(int j=0;j<4;++j){ // int nxt = fi[cl[j+1]]; // s += dp[nxt][cl[j]]; // } // rs = Math.min(rs,s); // // // }while(next_perm(cl)); // // out.print(rs); boolean next_perm(int[] a) { int len = a.length; for (int i = len - 2, j = 0; i >= 0; --i) { if (a[i] < a[i + 1]) { j = len - 1; for (; a[j] <= a[i]; --j) ; int p = a[j]; a[j] = a[i]; a[i] = p; j = i + 1; for (int ed = len - 1; j < ed; --ed) { p = a[ed]; a[ed] = a[j]; a[j++] = p; } return true; } } return false; } static long mul(long a, long b, long p) { long res = 0, base = a; while (b > 0) { if ((b & 1L) > 0) res = (res + base) % p; base = (base + base) % p; b >>= 1; } return res; } static long mod_pow(long k, long n, long p) { long res = 1L; long temp = k % p; while (n != 0L) { if ((n & 1L) == 1L) { res = mul(res, temp, p); } temp = mul(temp, temp, p); n = n >> 1L; } return res % p; } public static double roundD(double result, int scale) { BigDecimal bg = new BigDecimal(result).setScale(scale, RoundingMode.UP); return bg.doubleValue(); } } private static void solve() { InputStream inputStream = System.in; // InputStream inputStream = null; // try { // inputStream = new FileInputStream(new File("D:\\chrome_download\\exp.out")); // } catch (FileNotFoundException e) { // e.printStackTrace(); // } OutputStream outputStream = System.out; // OutputStream outputStream = null; // File f = new File("D:\\chrome_download\\"); // try { // f.createNewFile(); // } catch (IOException e) { // e.printStackTrace(); // } // try { // outputStream = new FileOutputStream(f); // } catch (FileNotFoundException e) { // e.printStackTrace(); // } InputReader in = new InputReader(inputStream); PrintWriter out = new PrintWriter(outputStream); Task task = new Task(); task.solve(1, in, out); out.close(); } public static void main(String[] args) { // new Thread(null, () -> solve(), "1", (1 << 18)).start(); solve(); } static class InputReader { public BufferedReader reader; public StringTokenizer tokenizer; public InputReader(InputStream stream) { reader = new BufferedReader(new InputStreamReader(stream), 32768); tokenizer = null; } public String nextLine() { String line = null; try { line = reader.readLine(); } catch (IOException e) { throw new RuntimeException(e); } return line; } public String next() { while (tokenizer == null || !tokenizer.hasMoreTokens()) { try { tokenizer = new StringTokenizer(reader.readLine()); } catch (IOException e) { throw new RuntimeException(e); } } return tokenizer.nextToken(); } public int nextInt() { return Integer.parseInt(next()); } public char nextChar() { return next().charAt(0); } public int[] nextArray(int n) { int res[] = new int[n]; for (int i = 0; i < n; ++i) { res[i] = nextInt(); } return res; } public long nextLong() { return Long.parseLong(next()); } public double nextDouble() { return Double.parseDouble(next()); } } }
C++11(clang++ 3.9) 解法, 执行用时: 4ms, 内存消耗: 504K, 提交时间: 2020-05-30 16:52:20
#include<bits/stdc++.h> using namespace std; vector<int> gao(vector<int> A,int step) { while(step) { int d1=A[1]-A[0],d2=A[2]-A[1]; if(d1==d2) return A; if(d1<d2) { int k=min(step,(d2-1)/d1); A[1]=A[1]+k*d1; A[0]=A[1]-d1; step-=k; } else { int k=min(step,(d1-1)/d2); A[1]=A[1]-k*d2; A[2]=A[1]+d2; step-=k; } } return A; } int getH(vector<int> cur,vector<int> root) { int h=0; if(cur==root) return 0; for(int i=30;i>=0;i--) { auto nxt=gao(cur,1<<i); if(nxt==root) continue; cur=nxt; h+=1<<i; } h++; return h; } int main() { vector<int> A(3); for(auto &a:A) cin>>a; vector<int> B(3); for(auto &b:B) cin>>b; sort(A.begin(),A.end()); sort(B.begin(),B.end()); auto A1=gao(A,0x3f3f3f3f); auto B1=gao(B,0x3f3f3f3f); if(A1!=B1) { cout<<"NO"<<endl; return 0; } cout<<"YES"<<endl; int ha=getH(A,A1); int hb=getH(B,A1); long long tot=0; if(ha<hb) swap(ha,hb),swap(A,B); tot+=ha-hb; A=gao(A,ha-hb); ha=hb; if(A==B) { cout<<tot<<endl; return 0; } for(int i=30;i>=0;i--) { auto A1=gao(A,1ll<<i); auto B1=gao(B,1ll<<i); if(A1==B1) continue; A=A1,B=B1; tot+=2ll<<i; } tot+=2; cout<<tot<<endl; }