列表

详情


NC50473. 跳跳棋

描述

跳跳棋是在一条数轴上进行的。棋子只能摆在整点上。每个点不能摆超过一个棋子。我们用跳跳棋来做一个简单的游戏:棋盘上有三颗棋子,分别在a,b,c这三个位置。我们要通过最少的跳动把他们的位置移动成x,y,z(注意:棋子是没有区别的)。
跳动的规则很简单,任意选一颗棋子,对一颗中轴棋子跳动。跳动后两颗棋子距离不变。一次只允许跳过一颗棋子。
写一个程序,首先判断是否可以完成任务。如果可以,输出最少需要的跳动次数。halma.png

输入描述

第一行包含三个整数,表示当前棋子的位置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;
 }

上一题