Codeforces Round962 (div3) A~D

A. Legs

题意:鸡兔同笼问题

思路:略,代码如下:

void solve(){
	int n;
	cin >> n;
	int ans = 0;
	ans += n/4;
	ans += (n%4)/2;
	cout << ans << endl;
}

B. Scale

题意:给定一个n*n的序列,给定一个数k,将该n*n的序列按顺序分割成若干个k*k个序列。

思路:间隔k个输出即可,代码如下:

void solve(){
	int n,k;
	cin >> n >> k;
	vector<string>map(n+1);
	for(int i = 0;i<n;i++){
		cin >> map[i];
	}
	for(int i = 0;i<n;i+=k){
		for(int j = 0;j<n;j+=k){
			cout << map[i][j] ;
		}
		cout << endl;
	}
}

C. Sort

题意:给定均为小写字母的字符串a和b,给定q个询问,每次询问给定l和r(左右区间),现在可以对该区间进行若干次操作,每次操作可以将区间内任意一个元素变为任意你想要的字母。求最终满足sorted(a[l..r])=sorted(b[l..r])的情况下,需要操作多少次。

思路:理解题意,区间内符合该要求的最少操作次数其实就是区间内不同的字母的个数,所以只需要统计区间内各个字母的个数即可,暴力会超时,这里用前缀和,统计26个字母的前缀个数和即可,代码如下:

void solve(){
	int n,q;
	cin >> n >> q;
	int cnt_a[200005][27];
	int cnt_b[200005][27];
	
	for(int i = 1;i<=n;i++){
		char a;
		cin >> a;
		
		for(int k = 1;k<=26;k++){
			if(k == a-'a'+1){
				cnt_a[i][k]=cnt_a[i-1][k]+1;
			}else{
				cnt_a[i][k]=cnt_a[i-1][k];
			}
		}
	}
	for(int i = 1;i<=n;i++){
		char b;
		cin >> b;
		for(int k = 1;k<=26;k++){
			if(k == b-'a'+1){
				cnt_b[i][k]=cnt_b[i-1][k]+1;
			}else{
				cnt_b[i][k]=cnt_b[i-1][k];
			}
		}
	}
	for(int i = 1;i<=q;i++){
		int l,r;
		cin >> l >> r;
		
		int same = 0;
		for(int k = 1;k<=26;k++){
			same += min(cnt_a[r][k]-cnt_a[l-1][k],cnt_b[r][k]-cnt_b[l-1][k]);
		}
		cout << (r-l+1-same) << endl;
	}
}

D. Fun

题意:给定一个n和x求a,b,c满足a+b+c<=x 并且 a*b + b*c + a*c<=n的解的个数。

思路:枚举a和b,然后对c进行二分查找,找到最大的满足a+b+c<=x并且a*b+b*c+a*c<=n的解的个数,另ans初始为0,每次加上该二分查找结果最大的c,就是该次枚举的a和b和c的解的数量(注意这样做时间复杂度为O(n*n*logn)会超时,所以这里需要对b的枚举进行剪枝,当a和b乘积大于n说明c无论如何都不存在了,那么直接break取消循环)。代码如下:

void solve(){
	int n,x;
	cin >> n >> x;
	int ans = 0;
	for(int a = 1;a<=x;a++){
		for(int b = 1;b+a<=x-1;b++){
			if(a*b>n)break;
			int l = 0,r = x-a-b+1;
			while(l+1 != r){
				int c = (l+r)>>1;
				if(a*b+b*c+a*c <=n){
					l = c;
				}else{
					r = c;
				}
			}
			ans += l;
		}
	}
	cout << ans << endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值