牛客周赛134
B题
资源合成与最大化问题,属于数学模拟或贪心类型
金:a,银:b,铜:c
x个铜换一个银,y个银换一个铜,换一次铜掉落一个铜
关键点在于掉落一个铜,那么就又有可能生成一个金,所以用while一直模拟,不能只模拟一轮
while(c>=x||b>=y)
{
b+=c/x;
c=c%x;
a+=b/y;
c+=b/y;
b=b%y;
}
cout << a <<endl;
C题
贪心+构造
贪心:对于每一位i,要保证数组不同元素尽可能多的同时b[i]尽可能大,这样后序元素有更多选择
不难看出数组b是非递减的,每一位要么是b[i-1]-1或者a[i]
看b中不同元素个数,放到set里,输出set大小
int mn=2e9;
for(i=1;i<=n;i++)
{
if(mn>a[i])
b[i]=a[i];
else b[i]=mn-1;
mn=b[i];
if(mn==0)
break;
}
set
for(i=1;i<=n;i++)
s.insert(b[i]);
cout << s.size() <<endl;
D题
二分或者双指针,区间计数问题,枚举左端点或者右端点
区间极值小于等于1
j是最远的左端点,如果p大小大于2,那么极值不可能为1,如果p大小等于2,并且二个元素相差大于1,极值也不为1
访问map,用p.begin()->first
for(i=1,j=1;i<=n;i++)
{
p[a[i]]++;
while(j<i&&p.size()>2||(p.size()2&&(abs(p.begin()->first-p.rbegin()->first)>1)))
{
p[a[j]]--;
if(p[a[j]]0)
p.erase(a[j]);
j++;
}
sum+=(i-j+1);
}
E题
思维题,规律题
有一个1
001 操作后变成011
010 操作后变成110
100 操作后变成101
有两个1
011 操作后变成101
101 操作后变成110
110 操作后变成011
三个
111变成000
只有可能进行上面两种操作
全1,输出0
全0,输出n
两个1的可以互变
通过多次操作,可以把所有的0都放到中间
这些0最后只会剩下一个0,就是答案
if(num0)
cout << 0 <<endl;
else if(nnum)
cout << n <<endl;
else cout << n-1 <<endl;
F题
浙公网安备 33010602011771号