SMU Summer 2024 Contest Round 2

目录

B.Consecutive

A.Sierpinski carpet

C.Minimum Width


B.Consecutive

给定长度为n的字符串s,q个询问,求在l到r的范围内有多少组俩个连续字符。

前缀和解决。和上一个相同就加一,否则就和上一个相等。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define inf 0x3f3f3f3f
#define pii pair<int,int>
const int mod=998244353;

void solve(){
	int n,q;
	cin>>n>>q;
	string s;
	cin>>s;
	vector<int>l(q),r(q);
	s=" "+s;
	for(int i=0;i<q;i++){
		cin>>l[i]>>r[i];
	}
//	if(n==1){
//		cout<<"0"<<endl;
//		return;
//	}
	vector<int>a(n+1);
	a[1]=0;
	for(int i=2;i<=n;i++){
		if(s[i-1]==s[i]){
			a[i]=a[i-1]+1;
		}else{
			a[i]=a[i-1];
		}
	}
	for(int i=0;i<q;i++){
		int ans=a[r[i]]-a[l[i]];
		
		cout<<ans<<endl;
	}
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	int oyyo=1;
// 	cin>>oyyo;
	while(oyyo--) {
		solve();
	}
	return 0;
}

A.Sierpinski carpet

C - Sierpinski carpet

中央区块完全"."单元格组成。其他八个区块是 (𝐾−1)(K−1) 级地毯。

先把地毯分成九块,除了中间那块,其它都是由左上角那块延申出来的。

#include<bits/stdc++.h>
using namespace std;
#define int  long long
#define endl '\n'
#define inf 0x3f3f3f3f
#define pii pair<int,int>

char a[1000][1000];

void solve(){
	
	int n;cin>>n;
	a[1][1]='#'; int c=1;
	for(int i=1;i<=pow(3,n);i++){
		a[i][0]='#';a[0][i]='#';
	}
	for(int z=1;z<=n;z++){
		c*=3;
		for(int i=1;i<=c;i++){
			for(int j=1;j<=c;j++){
				if(i>c/3||j>c/3){//除了左上角那块
					if((i>c/3&&i<=2*(c/3))&&(j>c/3&&j<=2*(c/3))){//中间那块
						a[i][j]='.';
					}
					else if(i<=c/3&&j>c/3){
						a[i][j]=a[i][j%(c/3)];
					}
					else a[i][j]=a[i%(c/3)][j];
				}
			}
		}
	}
	for(int i=1;i<=c;i++){
		for(int j=1;j<=c;j++){
			cout<<a[i][j];
		}
		cout<<endl;
	}
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	int oyyo=1;
	//cin>>oyyo;
	
	while(oyyo--) {
		solve();
	}
	return 0;
}

C.Minimum Width

D - Minimum Width

每个单词都不能被切割开来,只能占同一行,那么二分答案可以做,最长的可能结果就是所有字符加起来,再加上n-1个空格,最小的情况就是最长一个字符的长度,左右边界就确定了,那么就开始分,对于一个mid情况,遍历字符数组,若字符+空格情况满足要求,那么就放在同一行,否则行数+1,最后判断与题目要求函数是否一致。若多了,向高位取mid,反之取低位。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define inf 0x3f3f3f3f
#define pii pair<int,int>
const int mod=998244353;

int n,m;
int r,l,mid;
vector<int>a;
bool check(int x){
	int cnt=1;
	int sum=a[0];
	for(int i=1;i<n;i++){
		if(sum+a[i]+1<=x){
			sum+=a[i]+1;
		}else{
			cnt++;
			sum=a[i];
		}
	}
	if(cnt>m){
		return false;
	}else{
		return true;
    }
}
void solve(){
	cin>>n>>m;
	int sum=0;
	int max1=-1;
	for(int i=0;i<n;i++){
		int z;
		cin>>z;
		a.push_back(z);
		sum+=z;
		max1=max(max1,z);
	}
	r=sum+n-1;
	l=max1;
	int ans;
	while(l<=r){
		mid=(l+r)/2;
		if(!check(mid)){       
			l=mid+1;
		}else{
			r=mid-1;
			ans=mid;
		}
	}
	cout<<ans<<endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	int oyyo=1;
// 	cin>>oyyo;
	while(oyyo--) {
		solve();
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值