华为机试 (10/28)

整数与IP地址间的转换

原理:ip地址的每段可以看成是一个0-255的整数,把每段拆分成一个二进制形式组合起来,然后把这个二进制数转变成
一个长整数。
举例:一个ip地址为10.0.3.193
每段数字 相对应的二进制数
10 00001010
0 00000000
3 00000011
193 11000001
组合起来即为:00001010 00000000 00000011 11000001,转换为10进制数就是:167773121,即该IP地址转换后的数字就是它了。

的每段可以看成是一个0-255的整数,需要对IP地址进行校验

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
    
public class Main{
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = null;
        while ((str = br.readLine()) != null) {
            String[] ip = str.split("\\.");
            long num = Long.parseLong(br.readLine());
            //转10进制
            System.out.println(Long.parseLong(ip[0]) << 24 | Long.parseLong(ip[1]) << 16 |
                               Long.parseLong(ip[2]) << 8 | Long.parseLong(ip[3]));
            //转ip地址
            StringBuilder sb = new StringBuilder();
            sb.append(String.valueOf((num >> 24) & 255)).append(".").append(String.valueOf((num >> 16) & 255))
                .append(".").append(String.valueOf((num >> 8) & 255)).append(".").append(String.valueOf(num & 255));
            System.out.println(sb.toString());
        }
    }
}

#include <iostream>
#include <string>
#include <vector>
#include <stack>
using namespace std;

void test33(){
    string ip;
    long num;
    while (std::cin >> ip >> num) {
        vector<int> vec;
        string tmp;
        for (long i = 0; i < ip.length(); i++) {
            if (ip[i] != '.') {
                tmp += ip[i];
            }else{
                vec.push_back(atoi(tmp.c_str()));
                tmp.clear();
            }
            if (i == (ip.length()-1)){
                vec.push_back(atoi(tmp.c_str()));
                tmp.clear();
            }
        }
        long ipNum = 0;
        for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++) {
            //std::cout << *it << " ";
            ipNum = ipNum * 256 + *it;
        }
        std::cout << ipNum << "\n";
        
        stack<int> st;
        while (num > 0) {
            st.push(num % 256);
            num /= 256;
        }
        while (st.size() > 0) {
            if (st.size() == 1) {
                std::cout << st.top() << "\n" ;
            }else
                std::cout << st.top() << ".";
            st.pop();
        }
        
    }
}

int main(int argc, const char * argv[]) {
    // insert code here...
    test33();
    
}

判断两个IP是否属于同一个子网

子网掩码是用来判断任意两台计算机的IP地址是否属于同一子网络的根据。
子网掩码与IP地址结构相同,是32位二进制数,其中网络号部分全为“1”和主机号部分全为“0”。利用子网掩码可以判断两台主机是否中同一子网中。若两台主机的IP地址分别与它们的子网掩码相“与”后的结果相同,则说明这两台主机在同一子网中。
示例:
I P 地址  192.168.0.1
子网掩码  255.255.255.0
转化为二进制进行运算:
I P 地址 11010000.10101000.00000000.00000001
子网掩码 11111111.11111111.11111111.00000000
AND运算
    11000000.10101000.00000000.00000000
转化为十进制后为:
    192.168.0.0

I P 地址  192.168.0.254
子网掩码  255.255.255.0

转化为二进制进行运算:
I P 地址 11010000.10101000.00000000.11111110
子网掩码 11111111.11111111.11111111.00000000
AND运算
     11000000.10101000.00000000.00000000
转化为十进制后为:
     192.168.0.0
通过以上对两台计算机IP地址与子网掩码的AND运算后,我们可以看到它运算结果是一样的。均为192.168.0.0,所以这二台计算机可视为是同一子网络。
/*

  • 功能: 判断两台计算机IP地址是同一子网络。
  • 输入参数: String Mask: 子网掩码,格式:“255.255.255.0”;
  •           String ip1: 计算机1的IP地址,格式:“192.168.0.254”;
    
  •           String ip2: 计算机2的IP地址,格式:“192.168.0.1”;
    
  • 返回值: 0:IP1与IP2属于同一子网络; 1:IP地址或子网掩码格式非法; 2:IP1与IP2不属于同一子网络
    */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @Author erving
 * @date 2020/8/20
 **/
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        String str;
        while((str = bufferedReader.readLine()) !=null) {
            String[] mask = str.split("\\.");
            String[] ip1 = bufferedReader.readLine().split("\\.");
            String[] ip2 = bufferedReader.readLine().split("\\.");
            int res=0;
            for (int i = 0; i<4; i++){
                int a = Integer.parseInt(mask[i]);
                int b = Integer.parseInt(ip1[i]);
                int c = Integer.parseInt(ip2[i]);
                if(a<0||a>255 ||b<0 || b>255||c<0||c>255){
                    res = 1;
                    break;
                }
                if((b&a) != (a&c)){
                    res = 2;
                }
            }
            System.out.println(res);
        }
    }
}

#include<bits/stdc++.h>
#include<sstream>
using namespace std;

bool IpstrToUnit(string &ip_str, unsigned int& num)
{
    //1.将ipstring 中‘.’转化为' '.好进行字符串读取分割
    for(char &c:ip_str)
        if(c=='.')
            c=' ';
    //2.将ip按空格进行分割读取
    stringstream ss(ip_str);
    vector<int> seg;
    unsigned int val=0; 
    while(ss>>val)
        seg.push_back(val);
    
    //判断ip是否合法,IP 位数
    if(seg.size()!=4)
        return false;
    //判断ip是否合法,ip值的大小范围
    for(int v:seg)
        if(v<0 || v>255)
            return false;
    
    num=seg[0]<<24 | seg[1]<<16 | seg[2]<<8 |seg[3]<<0;
    return true;
}

int main()
{
    string mask, ip1, ip2;
    while(cin>>mask>>ip1>>ip2)
    {
        unsigned int mask_num,num1,num2;
        if(IpstrToUnit(mask,mask_num) && IpstrToUnit(ip1,num1) && IpstrToUnit(ip2,num2))
        {
            if((mask_num & num1)==(mask_num & num2))
                cout<<"0"<<endl;
            else
                cout<<"2"<<endl;
        }
        else
            cout<<"1"<<endl;
    }
    return 0;
}

称砝码

现有一组砝码,重量互不相等,分别为m1,m2,m3…mn;
每种砝码对应的数量为x1,x2,x3…xn。现在要用这些砝码去称物体的重量(放在同一侧),问能称出多少种不同的重量。
注:
称重重量包括0

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/*
*		现有一组砝码,重量互不相等,分别为m1,m2,m3…mn;
	每种砝码对应的数量为x1,x2,x3...xn。
	现在要用这些砝码去称物体的重量(放在同一侧),问能称出多少种不同的重量。
		注:
	称重重量包括0
	方法原型:public static int fama(int n, int[] weight, int[] nums) 
*/
public class Main {
	public static void main(String[] args) throws NumberFormatException, IOException {
		 // 1.高效读数据
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String mark = null;
        while ((mark = br.readLine()) != null) {
              int n = Integer.parseInt(mark);
            String[] s1 = br.readLine().split(" ");
            String[] s2 = br.readLine().split(" ");
            int[] weight = new int[s1.length];
            int[] nums = new int[s2.length];
            for (int i = 0; i < n; i++) {
                weight[i] = Integer.parseInt(s1[i]);
                nums[i] = Integer.parseInt(s2[i]);
            }
            System.out.println(fama(n, weight, nums));
        }
    }
    public static int fama(int n, int[] weight, int[] nums){
         int sum = 0;
         for(int i =0;i<n;i++){
               sum = sum + nums[i]* weight[i];
         }
         boolean[] weg = new  boolean[sum+1];
         weg[0] =true;
         weg[sum] = true;
		 // 三重循环,分别表示 n个砝码,weight.length 个种类,每个种类有 num.length 个数量
         for(int i =0; i< n; i++){
              for (int j = 0; j < nums[i]; j++) {
                  for(int k=sum; k>= weight[i];k--){
					  // weg[k-weight[i]]== true,意思就是 k-weight[i] + weight[i] == k,可以称出 k 重量
                      if(weg[k -weight[i]  ]){
                          weg[k] = true;
                      }
                  }
              }
         }
        int count = 0;
        for (boolean b : weg) {
            if (b) count++;
        }
        return count;
	}
}

#include <iostream>
using namespace std;
int main(){
    int n;
    while(cin>>n){
        int w[10]={0}; int num[10]={0};
        for(int i=0;i<n;i++)
            cin>>w[i];
        for(int i=0;i<n;i++)
            cin>>num[i];
        int v[12000]={0}; int maxw=0;
        for(int i=0;i<n;i++)
            maxw+=num[i]*w[i];
        v[0]=1;
        //类似背包问题
        for(int i=0;i<n;i++)   //砝码类别
            for(int j=maxw;j>=0;j--)  //背包容量
                for(int k=1;k<=num[i];k++){  //砝码数量
                    if(v[j]==1 && j+k*w[i]<=maxw)
                        v[j+k*w[i]]=1;
                }
        int res=0;
        for(int i=0;i<=maxw;i++)
            if(v[i]==1)
                res++;
        cout<<res<<endl;
    }
    return 0;
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值