PAT甲级--A+B and C (64bit) (20)


更多PAT甲级题解–acking-you.github.io

题目

OJ平台

题目解析

  • 开始看到这个数据范围,我瞬间就想到去用大数加减了。。然后就一直卡死了。。。

给大家看看我这大数加减的代码🤦‍♂️(为了实现能控制加减,用了函数指针,连我自己也叹服了🤣可就是过不了–可能时cmp处理的逻辑问题)

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
ll A,B,C;
vector<int>s;
int _add(int a,int b){
   return a+b;
}
int _minus(int a,int b){
   return a-b;
}
void add(string& s1,string& s2,int(*f)(int ,int)){
   int len = s1.size()>s2.size() ? s1.size() : s2.size();
   reverse(s1.begin(),s1.end());
   reverse(s2.begin(),s2.end());
   for(int i=0;i<len;i++){
      int a = i<s1.size() ? s1[i]-'0':0;
      int b = i<s2.size() ? s2[i]-'0':0;
      int base = f(a,b);
      s.push_back(base);
   }
   int up = 0;
   for(int i=0;i<s.size();i++){
      int base = s[i];
      s[i] = base%10+up;
      up = base/10;
   }
   if(up)
      s.push_back(up);
   reverse(s.begin(),s.end());
}
bool cmp(string& ss,bool flag1,bool flag2){
   if(flag1!=flag2)return flag1>flag2?false:true;
   int sz1 = s.size();
   int sz2 = ss.size();
   if(sz1 != sz2&&!flag1)return sz1>sz2?true:false;
   if(sz1 != sz2&&flag1)return sz1>sz2?false:true;
   for(int i=0;i<sz2;i++){
      int t = ss[i]-'0';
      if(t<s[i]&&!flag2)
         return true;
      else if(t>s[i]&&!flag2)
         return false;
      if(t<s[i]&&flag2)
         return false;
      else if(t>s[i]&&flag2)
         return true;
   }
   return false;
}
void solve(){
   int t;
   cin>>t;
   int n = t;
   string s1,s2,s3;
   for(int i=1;i<=n;i++){
      cin>>A>>B>>C;
      bool f1,f2,f3;
      f1 = A<0?true:false;
      f2 = B<0?true:false;
      f3 = C<0?true:false;
      unsigned long long t1,t2,t3;
      t1 = (unsigned long long)abs(A)>(unsigned long long)abs(B)?(unsigned long long)abs(A):(unsigned long long)abs(B);
      t2 = (unsigned long long)abs(A)>(unsigned long long)abs(B)?(unsigned long long)abs(B):(unsigned long long)abs(A);
      t3 = (unsigned long)abs(C);
      s1 = to_string(t1);
      s2 = to_string(t2);
      s3 = to_string(t3);
      bool f;
      if(f1==f2){
      add(s1,s2,_add);
      f = cmp(s3,f1,f3);
      }
      else{
         ll x = A+B;
         f = x>C;
      }
      printf("Case #%d: ",i);
      if(f)printf("true\n");
      else printf("false\n");
   }
}
int main(){
   solve();
   return 0;
 }

这波属实是傻了。。由于题目给定的数据量都告诉你了(不会超过long long),所以肯定根本就不至于使用大数加减的范畴。

由于给定了范围,那肯定可以利用分类讨论:

  1. 如果A > 0, B < 0 或者 A < 0, B > 0,sum是不可能溢出的。

  2. 如果A > 0, B > 0,sum可能会溢出,sum范围理应为(0, 2^64 – 2],溢出得到的结果应该是[-2^63, -2]是个负数,所以sum < 0时候说明溢出了。

  3. 如果A < 0, B < 0,sum可能会溢出,同理,sum溢出后结果是大于0的,所以sum > 0 说明溢出了

解题代码

将该溢出情况单独分出,其余情况直接一个else 即可

image-20211006185736320

#include <iostream>
using namespace std;
int main() {
    int n;
    cin>>n;
    for(int i = 1; i <= n; i++) {
        long long a, b, c;
        cin>>a>>b>>c;
        printf("Case #%d: ",i);
        long long sum = a + b;
        if(a > 0 && b > 0 && sum < 0) {
            cout<<"true\n";
        } else if(a < 0 && b < 0 && sum >= 0){
            cout<<"false\n";
        } else if(sum > c) {
            cout<<"true\n";
        } else {
            cout<<"false\n";
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值