每日两题day42
😴😴😴
每日两题
一、基础题
题目:76修地铁
思路:
计算题。依照题目要求计算即可。
代码(c++):
时间复杂度 O(1)
#include<bits/stdc++.h>
using namespace std;void go(){int n;cin>>n;int a,b,c,d;a =(n/5) * 2;//普通火把b = (n-5)/10 + (n>=5);//红石火把c = n/20;d = n*2 - c*2;//动力铁轨c *= 3;//普通铁轨cout<<a<<' '<<b<<' '<<c<<' '<<d<<endl;
}signed main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int t=1;//cin >>t;while(t--){go();}return 0;
}
二、提高题
题目:76选数
思路:
贪心构造题。异或运算的性质是:当 a = b a = b a=b 时 a ⊕ b = 0 a \oplus b = 0 a⊕b=0,当 a ≠ b a \neq b a=b 时 a ⊕ b = 1 a \oplus b = 1 a⊕b=1。将 1 1 1 到 n n n 的所有数都转为二进制后,为了让异或和最大,我们希望选择的数字组合中,每一位上 1 1 1 的个数为奇数。
具体做法是:从 1 1 1 开始,每次选择当前未被选择的最大 2 2 2 的幂(即 1 ( 1 2 ) , 2 ( 1 0 2 ) , 4 ( 10 0 2 ) , 8 ( 100 0 2 ) , … 1(1_2), 2(10_2), 4(100_2), 8(1000_2), \ldots 1(12),2(102),4(1002),8(10002),…),直到超过 n n n 为止。因为每个 2 2 2 的幂在二进制中只有一位是 1 1 1,这样选出来的数异或和能覆盖所有高位,保证结果最大。
所以,答案就是 1 + 2 + 4 + ⋯ + k 1 + 2 + 4 + \cdots + k 1+2+4+⋯+k,其中 k k k 是不超过 n n n 的最大 2 2 2 的幂。
可能需要的知识:
- 位运算:OI Wiki, B站:算法讲解003【入门】二进制和位运算【左程云】
代码(c++):
时间复杂度 O( log n \log n logn)
#include<bits/stdc++.h>
#define int long long
using namespace std;void go(){int n;cin>>n;int tmp = 1;int ans = 0;while (tmp<=n){ans += tmp;tmp *=2;}cout<<ans;el;
}signed main() {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int t=1;//cin >>t;while(t--){go();}return 0;
}
