贪心 + 找规律 之 hdu 5014 Number Sequence
/*
关键:贪心 + 找规律
0 1 2 3 4 5 6
肯定先从大的开始去找(贪心):
6:110 ---> 1:001 ==> 6^1 = 7
结果发现:
5: 101 ---> 2:010 ==> 5^2 = 7
4:100 ---> 3: 011 ==> 4^3 = 7
若 x ---> y,则区间 [x, y] 的所有值均可找到与其相匹配的数字。。。
*/
1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 typedef __int64 int64; 7 const int MAX_N = 100005; 8 int ini[MAX_N], N, ans[MAX_N]; 9 int64 sum; 10 11 void Ini() { 12 ini[0] = 1; 13 for (int i = 1; i < MAX_N; ++i) { 14 int myCount = 0; 15 int tmp = i; 16 while (tmp) { 17 ++myCount; 18 tmp >>= 1; 19 } 20 ini[i] = ((1 << myCount) - 1); 21 } 22 } 23 24 void Dfs(int n) { 25 if (n <= 0) return; 26 int tmp = (ini[n] ^ n); 27 for (int i = n; i >= tmp; --i) { 28 ans[i] = n + tmp - i; 29 } 30 Dfs(tmp - 1); 31 } 32 33 int main() { 34 //freopen("input.txt", "r", stdin); 35 Ini(); 36 while (~scanf("%d", &N)) { 37 for (int i = 0; i <= N; ++i) ans[i] = 0; // 一定要初始化,否则 WA 38 sum = 0; 39 Dfs(N); 40 int tmp; 41 for (int i = N; i >= 0; --i) { 42 sum += (int64)(ans[i] ^ i); 43 } 44 printf("%I64d\n", sum); 45 for (int i = 0; i <= N; ++i) { 46 scanf("%d", &tmp); 47 printf("%d", ans[tmp]); 48 if (i != N) { 49 printf(" "); 50 } 51 } 52 printf("\n"); 53 } 54 return 0; 55 }