4 条题解

  • 2
    @ 2024-10-5 16:26:16

    X4C 题解

    思路

    a+baa + b \to a 差值为 a|a|

    a+bba + b \to b 差值为 b|b|

    …………

    结论是后面会一直延续下去,都是 a|a|b|b|

    所以答案为 min(a,b,ab)\min(|a|,|b|,|a-b|)

    注:

    再证明一件事情,如果 a,ba, b 异号,答案一定为 00 (样例2的提示)。

    假设 a0ba \le 0 \le b

    用伪代码那来解释一下:

    while a+b > 0 : b = a + b
    
    结束后
    
    if a + b == 0 : {
        a = a + b  // a = 0
        b = a + b  // b = a
        abs(a - b) = 0
    } else : {
        while a + b < 0 : a = a + b
        while a + b > 0 : b = a + b
        因为 a b 的差一直减小,
        所以显然最后 a + b = 0
    }
    

    重点细节

    不开long long见祖宗

    Code

    #include <bits/stdc++.h>
    #define int long long
    #define endl() putchar('\n')
    #define space() putchar(' ')
    #define to_ans() putchar('&')
    #define to_debug() putchar('^')
    #define debug() puts("runs there")
    using namespace std;
    
    inline int read() {
    	int x = 0, f = 1;
    	char ch = getchar();
    	while (!isdigit(ch)) {
    		if (ch == '-') f = -1;
    		ch = getchar();
    	}
    	while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
    	return x * f;
    }
    
    void write(int x) {
    	if (x < 0) putchar('-'), x = -x;
    	if (x > 9) write(x / 10);
    	return void(putchar(x % 10 + 48));
    }
    
    int a, b;
    
    signed main() {
    	int T = read();
    	while(T--) {
    		a = read(), b = read();
    		if(a * b <= 0) write(0), endl();
    		else write(min({abs(a), abs(b), abs(a - b)})), endl();
    	}
    	return void(endl()), signed(0);
    }
    
    • 1
      @ 2024-9-19 12:57:35

      #include<bits/stdc++.h> using namespace std; int main() { int t; cin>>t; while(t--) { int a,b; cin>>a>>b; if(a<0&&b<0) cout<<min(abs(a),min(abs(b),abs(a-b)))<<"\n"; else if(a>0&&b>0) cout<<min(abs(a),min(abs(b),abs(a-b)))<<"\n"; else cout<<"0\n"; } return 0; }

      • 0
        @ 2025-6-25 16:14:01

        题解在此

        思路

        原题中 告诉我们 a 可以是 a + b,b也可以是a + b,算出a - b就是|a|,如果是b - a就等于|b|,列出min(abs(a),min(abs(b),abs(a - b))),后面看代码

        Code

        #include <bits/stdc++.h>
        using namespace std;
        int a,b;
        int main()
        {
            int n;
            cin >> n;
            for(int i = 1;i <= n;i++)
            {
                cin >> a >> b;
                if(a < 0 && b < 0) cout << min(abs(a),min(abs(b),abs(a - b))) << endl;
                else if(a > 0 && b > 0) cout << min(abs(a),min(abs(b),abs(a - b))) << endl;
                else cout << 0 << endl;
            }
            return 0;
        }
        
        • 0
          @ 2024-10-4 16:43:54

          考虑两种情况:

          1. a,ba,b 符号相同:

            考虑经过操作后 a,b,aba,b,\lvert a-b \rvert 会变成什么。:

          aa bb ab\lvert a-b \rvert
          操作1 a+ba+b bb a\lvert a \rvert
          操作2 aa a+ba+b b\lvert b \rvert

          可以看出只进行零次或一次操作后可以取到最小值。

          所以答案为 $\min(\lvert a \rvert,\lvert b \rvert,\lvert a-b \rvert)$。

          1. a,ba,b 符号不同

            答案为 00。下面给出理由:

            因为改变 a,ba,b 的位置不会影响结果,所以设 aa 为正数,bb 为负数。

            注意到每次操作都会改变 aabb 的值,并且由于 aabb 异号,如果不断将绝对值较小的数加到绝对值较大的数上,就会不断减小两者的差值:

            • 假如 a>b\lvert a\rvert>\lvert b\rvert ,我们执行 aa+b a\gets a+b a\lvert a\rvert 变小。
            • 假如 b>a\lvert b\rvert>\lvert a\rvert,我们执行 ba+b b\gets a+bb\lvert b\rvert 变小。

            由于每次操作都使得较大绝对值的数减小,因此可以类比辗转相减法,这种操作一定会在若干次后使得其中一个数变为 0。

          代码:

          #include<bits/stdc++.h>
          using namespace std;
          
          int main(){
          	int t;
          	cin>>t;
          	while(t--){
          		int a,b;
          		cin>>a>>b;
          		if((a<0&&b>0)||(a>0&&b<0)) cout<<0<<endl;
          		else cout<<min({abs(a),abs(b),abs(a-b)})<<endl;
          	}
          	return 0;
          }
          
          • 1

          信息

          ID
          56
          时间
          1000ms
          内存
          512MiB
          难度
          3
          标签
          递交数
          657
          已通过
          240
          上传者