我已编写此代码来计算数字范围之间的设置位数。我的程序编译得很好,并提供适当的输出。大输入和“超出时间限制”需要花费太多时间。
#define forn(i, n) for(long int i = 0; i < (long int)(n); i++)
#define ford(i, n) for(long int i = (long int)(n) - 1; i >= 0; i--)
#define fore(i, a, n) for(long int i = (int)(a); i < (long int)(n); i++)
long int solve(long int i) {
i = i - ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
}
int main() {
freopen("C:/Projects/CodeChef/SetBits/input.txt", "rt", stdin);
freopen("C:/Projects/CodeChef/SetBits/output.txt", "wt", stdout);
int tt;
long long int num1;
long long int num2;
scanf("%d", &tt);
forn(ii, tt) {
unsigned long int bits = 0;
unsigned long long int total_bits = 0;
scanf("%lld",&num1);
scanf("%lld",&num2);
fore(jj, num1, num2+1) {
bits = solve(jj);
total_bits += bits;
}
printf("%lld\n",total_bits);
}
return 0;
}
示例测试用例: -
示例输入: 3
-2 0
-3 4
-1 4
示例输出:
63
99
37
对于第一种情况,-2包含31 1后跟0,-1包含32 1和0包含0 1。因此,总数是63。
对于第二种情况,答案是31 + 31 + 32 + 0 + 1 + 1 + 2 + 1 = 99
具有大值的测试用例: -
10
-1548535525 662630637
-1677484556 -399596060
-2111785037 1953091095
643110128 1917824721
-1807916951 491608908
-1536297104 1976838237
-1891897587 -736733635
-2088577104 353890389
-2081420990 819160807
-1585188028 2053582020
有关如何优化代码的任何建议,以便花费更少的时间。所有有用的建议和答案将通过投票赞赏。 :)
答案 0 :(得分:1)
我不知道你在做什么,但我知道你可以清理你的代码,并且你可以内联你的功能。
此外,我已经冒昧地改编了“&#39;你编写代码,你正在使用像C这样的C ++,而那些定义只是严峻,将文件映射到stdio更糟糕。我还没有测试或编译代码,但它就在那里。
#include <fstream>
inline long int solve(long int i) {
i = i - ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
}
int main() {
long first, last;
unsigned count;
std::ifstream inf("C:/Projects/CodeChef/SetBits/input.txt");
std::ofstream off("C:/Projects/CodeChef/SetBits/output.txt");
inf >> count;
for(unsigned i=0u; i!=count; ++i) {
inf >> first >> last;
long total=0;
++last;
for(long t=first; t!=last; ++t) {
total+=solve(t);
}
off << total << '\n';
}
return 0;
}
关于如何加快速度的一些想法: