饿了么笔试 题解
1,第一题,可以发现每个数只有与不一样的数交换才有贡献,比第i位为1,i < j,只有s[j]为0才可以交换,统计一下前/后缀0/1的个数就可以了,然后加一下贡献
```
#include <iostream>
#include <vector>
using namespace std;
int main() {
string s;
while (cin >> s) {
long long res = 1;
vector<int> a0(s.size() + 1, 0), a1(s.size() + 1, 0);
for (int i = s.size() - 1; i >= 0; i --) {
if (s[i] == '0') {
a0[i] = a0[i + 1] + 1;
a1[i] = a1[i + 1];
res += 1ll * a1[i];
} else {
a0[i] = a0[i + 1];
a1[i] = a1[i + 1] + 1;
res += 1ll * a0[i];
}
}
cout << res << '\n';
}
}
// 64 位输出请用 printf("%lld")
```
2,可以hash一下每个图,每一行有多少个?每一行的值就是多少,11111代表五行每行都只有一个问号,后面就容易不少了。
#include <iostream>
#include <string>
using namespace std;
int main() {
int n;
cin >> n;
while (n --) {
string map[6];
int hash = 0;
for (int i = 0; i < 5; i ++) {
cin >> map[i];
int count = 0;
for (int j = 0; j < 5; j ++) {
if (map[i][j] != '#') count ++;
}
hash = hash * 10 + count;
}
// cout << "hash:" << hash <<'\n';
if (hash == 32223) {
cout <<0;
} else if (hash == 11111) {
cout << 1;
} else if (hash == 22311) {
cout << 4;
} else if (hash == 31111) {
cout << 7;
} else if (hash == 31323) {
cout << 6;
} else if (hash == 32323) {
cout << 8;
} else if (hash == 32313) {
cout << 9;
} else {
if (map[1][3] != '#') {
if (map[3][1] != '#') cout << 2;
else cout << 3;
} else {
cout << 5;
}
}
}
}
// 64 位输出请用 printf("%lld")
3,字典树比较模板的题,可以学一下字典树怎么写的,然后在字典树路径下贪心找最优解#牛客AI配图神器#
#include <iostream>
using namespace std;
const int N = 2e5 + 10;
int tr[N * 60][2], cnt[N * 60][2], ind;
void insert(int x, int mod) {
int p = 0;
for (int i = 31; i >= 0; i--) {
int v = x >> i & 1;
if (tr[p][v] == 0) tr[p][v] = ++ind;
cnt[p][v] += mod;
p = tr[p][v];
}
}
int getMaxXor(int x) {
int res = 0, p = 0;
for (int i = 31; i >= 0 ; i --) {
int v = x >> i & 1;
if (cnt[p][!v]) {
p = tr[p][!v];
res += 1 << i;
} else {
p = tr[p][v];
}
}
return res;
}
signed main() {
int n;
cin >> n;
int cnt = 0;
while (n --) {
int a, b;
cin >> a >> b;
if (a == 1) {
cnt ++;
insert(b, 1);
} else if (a == 2) {
cnt --;
insert(b, -1);
} else {
if (cnt == 0)
cout << -1 << '\n';
else cout << getMaxXor(b) << '\n';
}
}
}
// 64 位输出请用 printf("%lld")
```
#include <iostream>
#include <vector>
using namespace std;
int main() {
string s;
while (cin >> s) {
long long res = 1;
vector<int> a0(s.size() + 1, 0), a1(s.size() + 1, 0);
for (int i = s.size() - 1; i >= 0; i --) {
if (s[i] == '0') {
a0[i] = a0[i + 1] + 1;
a1[i] = a1[i + 1];
res += 1ll * a1[i];
} else {
a0[i] = a0[i + 1];
a1[i] = a1[i + 1] + 1;
res += 1ll * a0[i];
}
}
cout << res << '\n';
}
}
// 64 位输出请用 printf("%lld")
```
2,可以hash一下每个图,每一行有多少个?每一行的值就是多少,11111代表五行每行都只有一个问号,后面就容易不少了。
#include <iostream>
#include <string>
using namespace std;
int main() {
int n;
cin >> n;
while (n --) {
string map[6];
int hash = 0;
for (int i = 0; i < 5; i ++) {
cin >> map[i];
int count = 0;
for (int j = 0; j < 5; j ++) {
if (map[i][j] != '#') count ++;
}
hash = hash * 10 + count;
}
// cout << "hash:" << hash <<'\n';
if (hash == 32223) {
cout <<0;
} else if (hash == 11111) {
cout << 1;
} else if (hash == 22311) {
cout << 4;
} else if (hash == 31111) {
cout << 7;
} else if (hash == 31323) {
cout << 6;
} else if (hash == 32323) {
cout << 8;
} else if (hash == 32313) {
cout << 9;
} else {
if (map[1][3] != '#') {
if (map[3][1] != '#') cout << 2;
else cout << 3;
} else {
cout << 5;
}
}
}
}
// 64 位输出请用 printf("%lld")
3,字典树比较模板的题,可以学一下字典树怎么写的,然后在字典树路径下贪心找最优解#牛客AI配图神器#
#include <iostream>
using namespace std;
const int N = 2e5 + 10;
int tr[N * 60][2], cnt[N * 60][2], ind;
void insert(int x, int mod) {
int p = 0;
for (int i = 31; i >= 0; i--) {
int v = x >> i & 1;
if (tr[p][v] == 0) tr[p][v] = ++ind;
cnt[p][v] += mod;
p = tr[p][v];
}
}
int getMaxXor(int x) {
int res = 0, p = 0;
for (int i = 31; i >= 0 ; i --) {
int v = x >> i & 1;
if (cnt[p][!v]) {
p = tr[p][!v];
res += 1 << i;
} else {
p = tr[p][v];
}
}
return res;
}
signed main() {
int n;
cin >> n;
int cnt = 0;
while (n --) {
int a, b;
cin >> a >> b;
if (a == 1) {
cnt ++;
insert(b, 1);
} else if (a == 2) {
cnt --;
insert(b, -1);
} else {
if (cnt == 0)
cout << -1 << '\n';
else cout << getMaxXor(b) << '\n';
}
}
}
// 64 位输出请用 printf("%lld")
全部评论

这第二题直接暴力if else结果出bug了,调了半小时眼睛都快瞎了
。还是大佬这方法简单
佬有java吗

大家觉得这三道题都什么难度
佬,抱紧佬的大腿
太强了
int son[N * 30][2];
int idx = 0;
int num[N * 30];
void insert(int x)
{
int p=0;
for(int i=20;~i;i--)
{
int u=x>>i&1;
if(!son[p][u])son[p][u]=++idx;
p=son[p][u];
num[p] ++;
}
}
void del(int x)
{
int p=0;
for(int i=20;~i;i--)
{
int u=x>>i&1;
p=son[p][u];
num[p] --;
}
}
int query(int x)
{
int p=0,res=0;
for(int i=20;~i;i--)
{
int u=x>>i&1;
if(son[p][!u] && num[son[p][!u]])
{
res+=1<<i;
p=son[p][!u];
}
else p=son[p][u];
}
return res;
}
有没有大佬帮忙看看这种写法的删除有问题吗
第一题,直接用1的数量 * 0的数量 + 1,和您的这个方法有什么不同呢
第二题我拿每个不是#的字符对应的0~24坐标之和当key的,有重复的就额外再判断一下,光查坐标和纠错查了半个小时
1ll * a1[i];佬,前面✖️的是什么意思呢
相关推荐


点赞 评论 收藏
分享

点赞 评论 收藏
分享
03-10 15:25
北京邮电大学 算法工程师 

点赞 评论 收藏
分享
点赞 评论 收藏
分享