模拟赛第9套补题报告————————————————————————S12679

一.分数报告

T1100
T260
T330
T40
总分190

二.赛中概况

T1很快做完,T2,T4想了很久,T3暴力。

三.题目解析

T1

涂格子(paint)

时间限制:1秒        内存限制:256M

问题描述

现在有一个 n 行 m 列的网格纸,一开始每个格子都是白色的。

现在你可以任意挑选恰好 x 行和 y 列,将挑选的整行(整列)上的每一个格子涂成黑色, 问剩下多少个格子是白色的。

输入格式

第一行为 n,m,x,y,含义如上所示。

输出格式

一行一个整数表示答案。

样例输入
5312
样例输出
4
数据分布
对于 60% 的数据,1≤n,m≤100。
对于 100% 的数据,1≤n,m≤10^​9​​,1≤x≤n,1≤y≤m。

一道大水题,代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
	freopen("paint.in","r",stdin);
	freopen("paint.out","w",stdout);
	long long n,m,x,y;
	scanf("%lld%lld%lld%lld",&n,&m,&x,&y);
	long long cnt=n*m-x*m-y*(n-x);
	printf("%lld",cnt);
	fclose(stdin);
	fclose(stdout);
	return 0;
}

 T2

数串串(aba)

时间限制:1秒        内存限制:256M

问题描述

给定一个长度为 n 的字符串,求有多少个长度为 3 的子序列满足形如 ABA 的格式,即子序列中的第一个字母等于第三个字母,但它们都不等于第二个字母。

由不同位置的相同字符构成的子序列被认为是不同的子序列,见样例解释。

一个序列被称为字符串 s 的子序列,当且仅当该序列能仅通过 s 删除一部分字符得到。

输入格式

第一行一个正整数 n 表示字符串的长度。

第二行一个长度为 n 的字符串,保证字符串仅由小写英文字母构成。

输出格式

一行一个整数表示答案。

样例输入
7
abacabc
样例输出
9
样例解释

满足条件的子序列有 aba,aba,aca,aca,bab,bab,bcb,cac,cbc 共 9 个。

数据分布
对于 10% 的数据满足n≤300 ;
对于 60% 的数据满足n≤5×10​^4​​ ;
对于 100% 的数据满足1≤n≤10​^6​​ 。

前缀和题,刚开始数组会爆,就减少数组大小,60分。

代码:

#include<bits/stdc++.h>
using namespace std;
long long n;
char c[1000010];
long long a[1000010],cnt=0;
int main(){
	freopen("aba.in","r",stdin);
	freopen("aba.out","w",stdout);
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		cin>>c[i];
	}
	for(char i='a';i<='z';i++){
		memset(a,0,sizeof(a));
		for(int j=1;j<=n;j++){
			if(c[j]==i)a[j]++;
			a[j]+=a[j-1];
		}
		for(int j=1;j<=n;j++){
			if(c[j]!=i){
				cnt+=a[j]*(a[n]-a[j-1]);
			}
		}
	}
	printf("%lld",cnt);
	fclose(stdin);
	fclose(stdout);
	return 0;
}

 T3

取石子(pick)

时间限制:1秒        内存限制:256M

问题描述

有 n 堆石头排成一行,第 i 堆中有 a【i】a​​ 颗石子,Alice 和 Bob 打算玩一个取石子的博弈游戏,他们为每堆石子赋予了一个权值 b【i】,并规定一次操作为:选定一堆石子,从它本身和它前面的所有石子堆中各取走一颗。当前面有的石子堆中已经无石子的时候,不允许这样操作。对第 i 堆石子进行操作可以获得权值 bib​i​​。每堆石子对应的操作只能做 1 次。

现在他们不想玩无趣的博弈游戏了,他们想知道如果他们不断进行这样的操作,直到没有任何操作可以进行,在最优情况下,一共能获得多少权值。

形式化来说:给定 n 长序列 A=a【​1】​​,a【​2】​​,⋯,a【​n】​​,一次操作为选定一个 x,使 a【​1】​​,a【​2】​​,⋯,a【​x】​​ 均减少 1,但不允许选择会将某个 a【i】 减成负数的 x,操作完成之后获得权值 b【x】,每种 x 最多只能被选定 1 次,求经过任意多次操作之后能获得的最大权值。

输入格式

第一行为石子堆数 n

第二行为 n 个整数 a【​1】​​,a【​2​​】,⋯,a【​n】​​

第三行为 n 个整数 b【​1】​​,b​【2​​】,⋯,b​【n】​​

输出格式

一行一个整数,可获得的最大权值和

样例输入
5
62211
13245
样例输出
9
样例解释

可以对第 1,2,5 堆石子分别进行一次操作,共获得权值 1+3+5=9,最后的石子堆情况为 3 0 1 0 0

数据分布
对于 100% 的数据,1≤n≤5000,1≤a【​i】​​≤10​^9​​,1≤b【​i】​​≤10^​5​​
对于 30% 的数据,有额外限制:1≤n≤20
对于另外 30% 的数据,有额外限制:对于所有的 i,b【​i】​​=1

DP题,刚开始算不出来状态转移公式,就暴力,30分。

题解代码:

#include<bits/stdc++.h>
using namespace std;
long long n,a[5010],b[5010],gf=0,ma=-1;
long long dp[5005][5005];
int main(){
	freopen("pick.in","r",stdin);
	freopen("pick.out","w",stdout);
	scanf("%lld",&n);
	for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
	for(int i=1;i<=n;i++){
		scanf("%lld",&b[i]);
	}
	memset(dp,-1,sizeof(dp));
	for(int i=0;i<=n;i++){
		dp[0][i]=0;
	}
	for(int i=1;i<=n;i++){
		for(int j=0;j<=n;j++){
			dp[i][min(a[i],1ll*j)]=max(dp[i][min(a[i],1ll*j)],dp[i-1][j]);
		}
		if(a[i]>0){
			for(int j=1;j<=n;j++){
				if(dp[i-1][j]!=-1){
					dp[i][min(a[i]-1,1ll*j-1)]=max(dp[i][min(a[i]-1,1ll*j-1)],dp[i-1][j]+b[i]);
				}
			}
			
		}
	}
	long long ma=0;
	for(int i=0;i<=n;i++){
		ma=max(ma,dp[n][i]);
	}
	printf("%lld",ma);
	fclose(stdin);
	fclose(stdout);
	return 0;
}

 T4

健身计划(gym)

时间限制:1秒        内存限制:256M

问题描述

Setsuna 想要运动!

于是她安排了 n 天内的作息,作息用一个 01 字符串 s 表示,若 s​i​​ 为 0 则表示这天休息,为 1 则表示这天要去健身房运动。

但是连续 x 天的运动会积累 ​​x*(x+1)/2​​ 点疲劳值,也就是说字符串中每段长度为 xx 的极长连续 11 会带来 x(*x+1)/2​​​ 点疲劳值。

例如,若她的安排为 11101011 ,那疲劳值为 ​​​3*(3+1)​​/2+​1*(1+1)/2​​+​​2*(2+1)/2​​=10 点。

现在她可以把任意天运动日改成休息日,问最少需要改几天才能使得疲劳值小于等于 k。

输入格式

第一行包含两个整数 n,k 。

第二行包含一个长度为 n 的 01 串 s。

输出格式

输出一个整数,表示答案。

样例输入1
74
1110111
样例输出1

  1. 2
样例输入2

  1. 3 1
  2. 111
样例输出2
2
数据分布
对于 15% 的数据满足 n≤15 ;
对于 40% 的数据满足 n≤300 ;
对于 60% 的数据满足 n≤2000 ;
对于 100% 的数据满足1≤n≤10^​5​​,0≤k≤​n*(n+1)/2​​ 。

 题解代码:

#include<bits/stdc++.h>
using namespace std;
long long n,m;
long long pilao(long long x){
	return x*(x+1)/2;
}
long long cal(long long l,long long k){
	if(l<=k)return 0;
	l-=k;
	k++;
	return l%k*pilao(l/k+1)+(k-l%k)*pilao(l/k);
}
struct node{
	long long len,k;
	node(long long lenn=0,long long kk=0){
		len=lenn;
		k=kk;
	}
	bool operator<(const node& p) const{
		long long x=cal(len,k)-cal(len,k+1);
		long long y=cal(p.len,p.k)-cal(p.len,p.k+1);
		return x<y;
	}
};
priority_queue<node> q;
int main(){
	freopen("gym.in","r",stdin);
	freopen("gym.out","w",stdout);
	scanf("%lld%lld",&n,&m);
	long long cnt=0,now=0;
	for(int i=1;i<=n;i++){
		long long x;
		scanf("%1lld",&x);
		if(x)cnt++;
		if(!x||i==n){
			if(cnt){
				q.push(node(cnt,0));
				now+=pilao(cnt);
			}
			cnt=0;
		}
	}
	long long ans=0;
	while(now>m){
		ans++;
		node tmp=q.top();
		q.pop();
		now-=cal(tmp.len,tmp.k)-cal(tmp.len,tmp.k+1);
		q.push(node(tmp.len,tmp.k+1));
	}
	cout<<ans<<endl;
	fclose(stdin);
	fclose(stdout);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值