23.10.22周报

16日第一题:

题意:打出一字符串,每次单打一个字母,还有一次机会可以复制粘贴整个已打出的字符串。问打出完整的给定字符串s所需最小操作数。

思路:数据范围很小,可以暴力找出可复制粘贴的最大长度(50到1),然后计算答案即可。

第二题:

题意:给定字符串中,若存在一对下标相邻且在字母表上也相邻的字母,即为“丑对”,重新排序使字符串中没有丑对。

思路:最开始想到先用桶装下所有字母,这个思路大致没问题,但得开两个桶,把字母分为奇和偶,然后排序,倒出。

第三题:

题意:有n个员工(n为奇数),每个人有个l工资下限和r工资上限,总资金s大于等于l的和,问你最大的工资中位数是多少。

思路:最开始想到纯贪心模拟,后来发现模不是很出来,然后用二分贪心模拟,check函数也不是很好写,将员工分为三类,一类上限小于中位数,二类下限大于中位数,这两类都只发下限,还有一类一部分发下限,一部分发中位数。

18日一题:

题意:给一串数,每次操作可删去一数位,问最小操作数使数成为任意一正整数的平方。

思路:暴力枚举从sqrt(n)到1,判断其平方是否为数n的子串。

二题:

题意:给定一序列的m个限制条件,找出符合所有条件的任意序列。找不到输出NO。

每一条件包含三个数t,l,r。t=1则al到ar需单调不递减,t=0则al到ar需不满足单调不递减,即至少存在一对ai,ai+1满足ai严格大于ai+1。

思路:没做出来。大致思路为先初始化一字符串,把标1和标0的区间都标记一下,最后在只标过0的区间开头加个1,不知道思路对不对。

19日一题:

题意:给出n个区间的l和r范围,找出任意两区间ai和aj满足ail大于等于ajl,air小于等于ajr,即ai被aj包含。无满足条件答案则输出-1 -1

思路:开始觉得和之前的树状数组题很像,但后来发现不搭嘎。只需将r排个序,然后挨个检查ail是否大于等于ai+1的l,这里为什么只检查i和i+1就可以了呢,因为如果i和i+1不满足但和i+2满足条件,那么i+1也一定会和i+2满足条件,请自行画图理解。

二题:

题意:栅栏有n个木板组成,无相邻木板长度相同,则是好栅栏(即凹凸不平),可以花bi的钱让i栅栏长度加一,找出花最少钱让栅栏great again!

思路:没有思路,意思意思翻译一下,可能是dp或者二分,但想不到。

20日一题:

题意:一个木桶由k块木板组成,给n*k块板子,组n个桶,桶体积为其最短板子长度,最大桶和最小桶体积差距不超过l,问最大总体积.

思路:贪心模拟,先找出能用来作最大桶的木板,即长度与a1差距不超过l的木板,然后操作一下就行

代码如下:

#include <bits/stdc++.h>
using namespace std;
using ll=long long;

const int N=1e5+10;
int n,m,k,l;
int a[N];
ll ans;
void solve(){
	cin >> n >> k >> l;m=n*k;
	for(int i=1;i<=m;i++) cin >> a[i];
	sort(a+1,a+m+1);
	int idx=m;
	while(a[idx]-a[1]>l) idx--;
	if(m-idx>idx*(k-1)){cout << 0; return ;}
	int num=m-idx;
	//cout << idx << " " << num << endl;
	for(int i=idx;i;i--){
		if(num>=k-1){
			ans+=a[i];
			num-=k-1;
		}else if(num){
			i-=k-1-num;
			ans+=a[i];
			num=0;
		}else i-=k-1,ans+=a[i];
	}
	cout << ans;
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t=1;
	//cin >> t;
	while(t--) solve();
	return 0;
}
//make it count

二题是道数学题,想了会没做出来.

三题是道更难的数学题,也没做出来.

21日一题:

题意:有一台灯,从时刻0开始亮,时刻M断电,给一序列a,每到ai时刻台灯会转换状态(亮着的就关,关着的就亮),问插入一数a,使亮的总时间最长(也可不插入,如插入数后最长亮时不变).最长亮的时间是多少.

思路:同贪心模拟,不过比20号的一题高了一个档次.这里需要先记录下亮的时间和不亮的时间,最开始我用一个变量去记录,发现后面比较不了,于是改为前缀和数组去记录,但操作难度对我来说有点高.插入一数后,前面亮着的不变,后面不亮的时间变为亮的时间,所以需要前缀和.

代码如下:

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
using PII=pair<int,int>;

const int N=1e5+10;
int n,m;
int a[N],len[N];
ll sum1[N],sum2[N],ans;
void solve(){
	cin >> n >> m;
	for(int i=1;i<=n;i++) cin >> a[i];a[n+1]=m;n++;
	for(int i=1;i<=n;i++){
		len[i]=a[i]-a[i-1];
		if(i&1){
			ans+=len[i];
			sum1[i]=sum1[i-1]+len[i];
			sum2[i]=sum2[i-1];
		}else{
			sum2[i]=sum2[i-1]+len[i];
			sum1[i]=sum1[i-1];
		}
	}
	for(int i=1;i<=n;i++) ans=max(sum1[i-1]+len[i]-1+sum2[n]-sum2[i],ans);
	cout << ans;
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t=1;
	//cin >> t;
	while(t--) solve();
	return 0;
}
//make it count

二题:

题意:一串数中连续的单一数字被称为block,如00,11,99为长度为2的block,27734中2,3,4为长度1的block,77为长度2的block,给一数n,有0到10的n次幂减一(前缀会自动填充0)个数,问长度从1到n的block各在所有数中有多少.

思路:没做出来.这道题能发现长度为n的block恒为10,所以我打算从n开始,倒着算答案,i-1的block可以看成从长度i的block中选出来的.但更详细的规律没有找到,且网上的思路好像也和我的不一样.

  22日打了个比赛,前三道题做的挺快的,但止步于此,有看了下但没做出来的数学题,模拟题等.

  最近感觉状态不是很好,不知道是因为这几天的每日三题都有点难,还是真的状态不好。

  今天看到学长拿了牌子,帅的一。

  今后打算把更多精力投入到算法学习中来,绩点差不多就ok了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值