题解西电OJ (Problem 1007 -做一名正气的西电人 )--长整型计算

 

Description

  一天,wm和zyf想比比谁比较正气,但正气这种东西无法量化难以比较,为此,他们想出了一个方法,两人各写一个数字,然后转化为二进制,谁的数字中二进制1多谁就比较正气!

Input
  输入包含多组数据,EOF结束。
  每组数据包含两行,代表两个非负整数a,b(0<=a,b<10^100,不含前导0),a为wm写的数字,b为zyf写的数字。
Output
  每组数据输出一行,输出正气的西电人名字"wm"或"zyf",如果两人的数字中二进制1一样多就输出"neither"。

Sample Input
15
16
17
18
20
19
Sample Output
wm
neither
zyf

题目分析:

由于a,b是非常大的长整数,因此需要长整数算法,对于一个整数来说,求其二进制中1的个数就是 模2,然后再除2,直到这个数变为0 ,看看模2的过程中出现了几次1。那么对于长整数也是这样的,因为长度范围是100位,如果我们用一个数组,每个数组项标示5位,这样可以减少进位的计算。具体代码如下

 1 #include <iostream>
 2 #include <string.h>
 3 #include <stdlib.h>
 4 using namespace std;
 5 
 6 
 7 int com(char * str)
 8 {
 9     int res = 0 ;
10     int i , j , k , l ;
11     l = 0 ;
12     unsigned int tmp[30];
13     for(i = strlen(str); i > 0 ; i -= 5){
14         j = i - 5;
15         k = j > 0 ? j:0 ;
16         const char * nump = (str+k);
17         tmp[l++] = atoi(nump);
18         str[k] = '';
19     }
20     unsigned int num[30];
21     for(i = 0 ; i < l ; i++){
22         num[i] = tmp[l-i-1] ;
23     }
24     
25     for(i = 0 ; num[l-1] != 0 || i < l-1;){
26         k = 0 ;
27         for(j = i ; j < l ; j++){
28             num[j] = (k*100000) + num[j] ;
29             k = num[j]%2 ;
30             num[j] /= 2 ;
31         }
32         if(k){
33             res++;
34         }
35         while(num[i] == 0){
36             i++ ;
37         }
38     }
39     return res;
40 }
41 
42 int main()
43 {
44     string wm ;
45     string zyf ;
46     while(cin >> wm >> zyf){
47         int wm1 = com((char *)wm.c_str());
48         int zyf1 = com((char *)zyf.c_str());
49         if(wm1>zyf1){
50             cout << "wm" << endl;
51         }else if(wm1<zyf1){
52             cout << "zyf" << endl ;
53         }else{
54             cout << "neither" << endl ;
55         }
56     }
57     return 0 ;
58 }
原文地址:https://www.cnblogs.com/liucheng/p/3683655.html