Codeforces Round #642 (Div. 3)(F题待补充)

A题

https://codeforces.com/contest/1353/problem/A
看提示找规律 : n = 1, 结果为 0;n = 1,结果为 m;n = 2,结果为 2m

#include <iostream>
#include <cstdio>
using namespace std;
 
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		int len,sum;
		scanf("%d%d",&len,&sum);
		if(len==1){
			printf("0\n");
			continue;
		}
		if(len==2){
			printf("%d\n",sum);
			continue;
		}
		if(len>2)
		    printf("%d\n",2*sum);
	}
	return 0;
}

B题

https://codeforces.com/contest/1353/problem/B
将a 数组和 b 数组分别进行排序,比较 a数组的最小数和b数组最大数的大小,判断是否需要交换,若需要,则a 数组从前往小到大逐个交换, b 数组从大到小逐个交换

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;

int a[40],b[40];
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		int n,k;
		scanf("%d%d",&n,&k);
		for(int i = 0; i<n; ++i){
			scanf("%d",&a[i]);
		}
		for(int i = 0; i<n; ++i){
			scanf("%d",&b[i]);
		}
		sort(a,a+n);
		sort(b,b+n);
		for(int j = 0; j<k;++j){
			if(a[j]<b[n-j-1])
				swap(a[j],b[n-j-1]);
			else
				break;
		}
		int sum = 0;
		for(int i = 0; i<n; ++i){
			sum+=a[i];
		}
		printf("%d\n",sum);
	}
	return 0;
}

C题

https://codeforces.com/contest/1353/problem/C
思路:所有方块移动到中心花费的次数最小。从中心开始第一层的 8个方块只需移动 1部,第 2层的16个方块只需移动2步,依次类推。因此,通过计算每一圈的总步数,相加即可得到最终结果
在这里插入图片描述

#include <iostream>
#include <cstdio>
using namespace std;
#define LL long long
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		LL n;
		scanf("%lld",&n);
		LL val = n/2;
		LL sum = 0;
		for(LL i = 1;i<=val; ++i){
			sum += i*8*i;
		}
		printf("%lld\n",sum);
	}
	return 0;
}

D题

https://codeforces.com/contest/1353/problem/D
本题分割数组的方法类似于二分,因此先进行模拟二分操作,arr[mid].first存储序列长度的大小的相反数(负数便于main函数中对数组进行排序时,不用重新编写排序函数),second存储划分区间后所要赋值的数组元素的下标。模拟二分后再根据子序列的长度(若长度相同,则根据数组元素的下标,小的说明赋值需要优先)进行排序,最后赋值。

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

pair<int,int>arr[200005];
int val[200005];
void dfs(int l,int r){
	//模拟二分 
	if(l<=r){
		int mid = l+(r-l)/2;
		arr[mid].first = l-r-1;
		arr[mid].second = mid;
		dfs(l,mid-1);
		dfs(mid+1,r);
	}
}
int main(){
	//pair默认排序是从小到大,先比较first,在first相等的情况下比较second
	int t;
	scanf("%d",&t);
	while(t--){
		int n;
		scanf("%d",&n);
		dfs(1,n);
		sort(arr+1,arr+n+1);
		for(int i = 1; i<=n; ++i){
			val[arr[i].second] = i;
		}
		for(int i = 1; i<=n;++i){
			printf("%d ",val[i]);
		}
		printf("\n");
	}
	return 0;
}

E题

https://codeforces.com/contest/1353/problem/E
满足条件的数的情况:(1)全为 0 (2)第 i 位为 1 ,其余位全是 0 (3)1按周期出现
利用dp[i]记录字串[1,i]区间第i位为1,需要更新原字符串中的值的最小个数(1变0 / 0变1)

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;

const int N = 1000005;
char arr[N];
int dp[N],sum[N];
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		int n,k;
		scanf("%d%d",&n,&k);
		scanf("%s",arr+1);
		//利用前缀和计算 1 的个数 
		for(int i=1; i<=n;++i){
			sum[i] = sum[i-1]+(arr[i]=='1');
		}
		//第 j 位为1,将前面的1都变为 0  需要更新的个数
		for(int j = 1; j<=n;++j){
			dp[j] =  sum[j-1]+(arr[j]=='0');
		} 
		//dp[i]取到第i位(2)和(3)两种情况需要更新的个数的最小值
		for(int i = k+1; i<=n;++i){
			dp[i] = min(dp[i],dp[i-k]+sum[i-1]-sum[i-k]+(arr[i]=='0'));//上一个 1 的位置 
		}
		int res = sum[n];
		//将第 i 位后的 1 都置为 0  
		for(int i = 1; i<=n;++i){
			res = min(res,dp[i]+sum[n]-sum[i]);
		}
		printf("%d\n",res);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值