3 条题解

  • 2
    @ 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;
    }
    
    • 2
      @ 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; }

      • 1
        @ 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

        信息

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