Summary
今天的题终于少了一些,不过有点坑,被罚时罚死了 /(ㄒoㄒ)\~~
昨天 题目预测 命中率 2/4=50%,没想到只有 4 题 ヾ(≧▽≦*)o
Information
No. | Title | AC/Submit |
---|---|---|
A | 保龄球-map | 55/199 |
B | 查字典 | 62/88 |
C | 眼红的Medusa | 49/151 |
D | 指数序列 | 16/95 |
Problem A: 保龄球-map (1687) [55/199]
Tips
一个简单的签到题,用 map 保存瓶子的位置即可
注意:本题使用 cin
cout
会 TLE !!!(cost + 20)
Code
#include <bits/stdc++.h>
using namespace std;
int main()
{
long long n,num,m;
map<long long,int>ma;
scanf("%lld",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&num);
ma[num]=i;
}
scanf("%lld",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&num);
printf("%d\n",ma[num]);
}
return 0;
}
Problem B: 查字典 (1678) [62/88]
Tips
一个模板题,可以练练 map
和 string
好吧 ╮(╯-╰)╭ 这才是真正的签到题。
Code
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,num,m;
map<string,int>ma;
string word;
cin>>n;
while(n--)
{
cin>>word>>num;
ma[word]=num;
}
cin>>m;
while(m--)
{
cin>>word;
cout<<ma[word]<<endl;
}
return 0;
}
Problem C: 眼红的Medusa (1686) [49/151]
Tips
这题有个坑,绕过去就不难了。
输出一行,为获得两个奖项的人的编号,
按在科技创新奖获奖名单中的先后次序输出。
Code
#include <bits/stdc++.h>
using namespace std;
int main()
{
long long n,num,m,kc[100000];
map<long long,int>ma;
cin>>n>>m;
for(int i=0;i<n;i++)
{
cin>>kc[i];
ma[kc[i]]++;
}
for(int i=0;i<m;i++)
{
cin>>num;
ma[num]++;
}
for(int i=0;i<n;i++)
{
if(ma[kc[i]]==2)cout<<kc[i]<<" ";
}
return 0;
}
Problem D: 指数序列 (1677) [16/95]
Tips
一道数学题,分析一下就出来了:
题目分析:
给出 a1 ,a2 ,…,an,可以对应的找到 2a1 ,2a2 ,…,2an
问至少添加多少个 2x 的数(x 为非负整数),能使这个序列所有整数和为 2v-1,其中 v 是任意的。
思路分析:
掏出万能的 Win10 计算器观察二进制,发现要想满足题目要求,
只需 使二进制所有位都为 1,也就是要 找最高位之前 0 的个数,用一个数进行补充。
首先题目中的数据给的就是二进制位数,那么现在只需关心两方面:
- ai 的最高位数
- 最高位之前有几个 1(减一下得到 0 的数量)
那么再来看一下数据范围:每个数最大 2e9,肯定不能循环遍历,那就用新讲的 map 存。
map 的 key 保存第几个二进制位(即 ai ),value 保存这位有几个。
这时你会发现题中还有一个重要信息:“这个序列保证单调不降”
这就说明两个同样的位数会产生进位,
解决方案也很简单:map 存储的时候个数只要有 2 个就进位
思路理解了,写代码就不难了。
Code
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
long long maxa=0,num,cnt=0,ans;
map<long long,int>ma;
scanf("%lld",&n);
while(n--)
{
scanf("%lld",&num);
ma[num]++; //个数++
if(ma[num]==2)
{
for(long long i=num;ma[i]==2;i++) //进位
{
ma[i]-=2;
ma[i+1]++;
}
}
}
for(map<long long,int>::iterator it=ma.begin();it!=ma.end();it++)
{
if(it->second!=0) //-2之后会留下这个pair,所以要判断一下是否被减到0
{
cnt++; //计算1的个数
if(it->first>maxa)maxa=it->first; //找到最大位数
}
}
printf("%lld",maxa<cnt?0:maxa-cnt+1);
return 0;
}