3 条题解

  • 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);
    }
    
    • 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; }

      • 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
        标签
        递交数
        656
        已通过
        239
        上传者