杭电OJ-ACM2057(A + B Again)

问题描述

我们的HDOJ一定有很多+B问题,现在有一个新的问题。给你两个十六进制整数,你的任务是计算它们的总和,并打印成十六进制整数。容易吗?AC!

输入

输入包含几个测试用例,请处理到文件的末尾。
每种情况由两个十六进制整数a和B组成,由空白分隔。
A和B的长度均小于15。

输出

对于每个测试用例,将A和B的十六进制的和打印成一行。

实例输入

+A -A
+1A 12
1A -9
-1A -12
1A -AA

实例输出

0
2C
11
-2C
-90

法一(Java【巨麻烦】版):

在此种极麻烦的方法中,答主采用的是传统的进制转换法,先将两个输入的十六进制数转换成十进制,在通过两个十进制的加减,对其结果转换回十六进制,故十分繁琐。

  1. 输入的处理

由于输入可能含有“+”号,所以我们可以使用字符串进行输入;当输入含有“+”号时,通过Java库内的substring进行字符串截取(从第二个字符开始截取到末尾,即索引下标为1的字符),使得“+”号消失而只剩下正整数。

String A = kc.next();
            String B = kc.next();
            char a = A.charAt(0);
            char b = B.charAt(0);
            if (a == '+') {
                A = A.substring(1);
            }
            if (b == '+') {
                B = B.substring(1);
            }
  1. 十六进制转换为十进制以及十进制加减

对于十六进制的转换,我们可以事先定义一个新的静态(static)方法进行处理.

static long f1(String a){
           long sum=0;//因为题干中所给的是最高15位数,必须使用long进行定义(笔者起初因为int定义一直被系统判为WR)
           for(int i=0;i<a.length();i++){
               char c = a.charAt(a.length() - i - 1);
               if(c>='A'&&c<='F'){
                   c=(char)(c -55);
               }
               if(c>='0'&&c<='9'){
                   c=(char)(c-48);
               }
               sum+=c*Math.pow(16,i);
           }
           return sum;
    }

但是同时需注意,当输入的字符串为“-”开头时,在此方法中显然会出错!为解决此问题,我们可以讨论输入的a与b正负号的问题,即当a或b为负数时,我们可以在方法外加“-”号,而方法的输入字符串为其第二位开始到末尾(删去“-”号).

long sum=0;
if(a=='-'&&b=='-'){
                sum=-(f1(A.substring(1))+f1(B.substring(1)));
            }
            else if(a!='-'&&b=='-'){
                sum=f1(A)-f1(B.substring(1));
            }
            else if(a=='-'&&b!='-'){
            sum=f1(B)-f1(A.substring(1));
            }
            else{
            sum=f1(A)+f1(B);
            }
  1. 十进制转换回十六进制

在此转换过程中,我们采用整除十六取余依次加在字符串前的方式书写一个新的静态方法;若上面sum的值为负数,那么我们采取类似的方式,先对sum取负,再在调用的静态方法外面添上负号。、

static String f2(long a) {
        String x = "";
        long r;
        if (a == 0) {
            return "0";
        } else {
            while (a != 0) {
                r = a % 16;
                if (r >= 10) {
                    x = (char) (r + 55) + x;
                } else {
                    x = Long.toString(r) + x;
                }
                a = a / 16;
            }
            return x;
        }
if(sum<0){
                sum=-sum;
                System.out.println("-"+f2(sum));
            }
            else{
                System.out.println(f2(sum));
            }
  1. 整合整体代码

对于整体代码的外框架,应当使用while循环实现多组测试样例的输入,同时因起始输入为字符串,则循环当采用“....hasNext()”进行多组循环。

整体代码为——

import java.util.Scanner;

public class oj2057 {
    public static void main(String[] args) {
        Scanner kc = new Scanner(System.in);
        while (kc.hasNext()) {
            String A = kc.next();
            String B = kc.next();
            char a = A.charAt(0);
            char b = B.charAt(0);
            long sum=0;
            if (a == '+') {
                A = A.substring(1);
            }
            if (b == '+') {
                B = B.substring(1);
            }
            if(a=='-'&&b=='-'){
                sum=-(f1(A.substring(1))+f1(B.substring(1)));
            }
            else if(a!='-'&&b=='-'){
                sum=f1(A)-f1(B.substring(1));
            }
            else if(a=='-'&&b!='-'){
            sum=f1(B)-f1(A.substring(1));
            }
            else{
            sum=f1(A)+f1(B);
            }
            if(sum<0){
                sum=-sum;
                System.out.println("-"+f2(sum));
            }
            else{
                System.out.println(f2(sum));
            }
        }
    }
    static long f1(String a){
            long sum=0;
           for(int i=0;i<a.length();i++){
               char c = a.charAt(a.length() - i - 1);
               if(c>='A'&&c<='F'){
                   c=(char)(c -55);
               }
               if(c>='0'&&c<='9'){
                   c=(char)(c-48);
               }
               sum+=c*Math.pow(16,i);
           }
           return sum;
    }
    static String f2(long a) {
        String x = "";
        long r;
        if (a == 0) {
            return "0";
        } else {
            while (a != 0) {
                r = a % 16;
                if (r >= 10) {
                    x = (char) (r + 55) + x;
                } else {
                    x = Long.toString(r) + x;
                }
                a = a / 16;
            }
            return x;
        }
    }
}

法二(C++【极简】版):

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
杭州电子科技大学在线评测系统(杭电OJ)中的题目1000-1100是一系列编程题,我将分别进行回答。 1000题是一个简单的入门题,要求计算两个整数的和。我们可以使用一个简单的算法,读取输入的两个整数,然后将它们相加,最后输出结果即可。 1001题是一个稍微复杂一些的题目,要求实现字符串的逆序输出。我们可以使用一个循环来逐个读取输入的字符,然后将这些字符存储在一个数组中。最后,我们可以倒序遍历数组并将字符依次输出,实现字符串的逆序输出。 1002题是一个求最大公约数的问题。我们可以使用辗转相除法来解决,即先求出两个数的余数,然后将被除数更新为除数,将除数更新为余数,直至两个数的余数为0。最后的被除数就是最大公约数。 1003题是一个比较简单的排序问题。我们可以使用冒泡排序算法来解决,即每次比较相邻的两个元素,如果它们的顺序错误就交换它们的位置。重复这个过程直至整个数组有序。 1100题是一个动态规划问题,要求计算给定序列中的最长上升子序列的长度。我们可以使用一个数组dp来保存到达每个位置的最长上升子序列的长度。每当遍历到一个位置时,我们可以将其和之前的位置比较,如果比之前位置的值大,则将其更新为之前位置的值加1,最后返回dp数组的最大值即可。 以上是对杭电OJ1000-1100题目的简要回答,涉及了一些基本的编程知识和算法思想。希望对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值