[EOJ] 实训题 P3036. 按数据中1的位数排序
先把题目地址贴出来:[EOJ] 实训题 P3036. 按数据中1的位数排序
所有数据在内存中都是以二进制形式存放的,其中有一些位是 1,而另一些位是 0。
例如,整数 100 的二进制表示为 1100100,其中 1 的位数是 3;整数 15 的二进制表示为 1111,其中 1 的位数是 4;整数−15 的 64 位二进制表示为 1111111111111111111111111111111111111111111111111111111111110001,其中 1 的位数是61。
现在有 N 个整数,要求按照 64位二进制补码表示中 1 的位数从大到小进行排序。若两个数的二进制表示中 1 的位数相同,则按照数本身值由小到大排序。
例如:数 100,15,0,30,7,−15,100,−100 排序后的结果为 :
−15,−100,15,30,7,100,100,0。
输入格式
第 1 行:整数 T (1≤T≤10) 为问题数
第 2 行:第一个问题中的 N(1≤N≤10000)
第 3 行:N 个待排序的数 (−1018≤数≤1018),每两个数之间由一个空格分隔。
第 4 ~T×2+1 行:后面问题的数据,格式与第一个问题相同。
输出格式
对于每个问题,输出一行问题的编号(0 开始编号,格式:case #0:
等),然后在一行中输出排序后的数。格式为:以一个空格分隔每两个数。
样例
Input
3
1
1234
5
100 15 0 30 7
10
1 1 3 4 5 6 -7 -8 1234567 10000000
Output
case #0:
1234
case #1:
15 30 7 100 0
case #2:
-7 -8 1234567 10000000 3 5 6 1 1 4
AC代码如下:
#include <iostream>
#include <algorithm>
#include <cstdio>
#define MAXN 10009
using namespace std;
typedef long long ll;
struct my_sort
{
ll num; // 输入的数
int cnt; // '1'的个数
};
bool cmp(my_sort p1, my_sort p2)// sort
{
return (p1.cnt == p2.cnt) ? p1.num < p2.num : p1.cnt > p2.cnt;
}
int q_cmp(const void* a, const void* b)// qsort
{
struct my_sort d1,d2;
d1=*((struct my_sort *)a);
d2=*((struct my_sort *)b);
if(d2.cnt!=d1.cnt)
return d2.cnt-d1.cnt;
else
{
if(d1.num>d2.num) return 1;
else return -1;
}
}
int main()
{
int T, i, j, N;
cin >> T;
for(i = 0; i < T; ++i)
{
my_sort S[MAXN];
cin >> N;
for(j = 0; j < N; ++j)
{
cin >> S[j].num;
S[j].cnt = 0;
ll and_num = 1, k = 0;
while(k < 64) // Core code
{
// 通过初始用1,每次左移1位与我们需要判断的数据作‘&’操作,来判断有多少个‘1’。
if(S[j].num & and_num) S[j].cnt++;
and_num = and_num << 1;
k++;
}
}
//sort(S, S+N, cmp);
qsort(S, N, sizeof(S[0]), q_cmp);
printf("case #%d:\n", i);
for(j = 0; j < N; ++j)
cout << S[j].num << ((j == N - 1) ? '\n' : ' ');
}
return 0;
}