Codeforces Round 719 (Div. 3)除F2题外补题报告

得分情况

A题AC
B题AC
C题TLE在样例2
(题简单,脑袋没转过弯来)

补题情况

全部AC

错题分析

C题

题目大意

构造一个n∗n的矩阵,使得相邻的两个格子填的数不能相邻。

初次思路

暴力枚举。

正解思路

我们可以把奇偶分开填入矩阵,可知,除了2*2无解,别的情况都行。

正解代码

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

错误原因

题意理解错了。

D题

题目大意

给出T组序列a,长度为N,询问有多少对 ( i , j ) (i,j) (i,j)满足 i < j i<j i<j a j − a i = j − i a_j −a_i =j−i ajai=ji

初次思路

暴力枚举。

正解思路

a j − a i = j − i a_j −a_i =j−i ajai=ji变形为 a j − j = a i − i a_j −j =a_i−i ajj=aii,然后统计值与下标的差,再用排列组合公式求出数量—— n ∗ ( n − 1 ) / 2 n*(n-1)/2 n(n1)/2,最后求和。

正解代码

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int vis[400005];
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		memset(vis,0,sizeof vis);
		int n;
		scanf("%d",&n);
		for(int i=1;i<=n;i++){
			int x;
			scanf("%d",&x);
			vis[x-i+n]++;
		}
		long long ans=0;
		for(int i=0;i<=2*n;i++){
			ans+=1ll*vis[i]*(vis[i]-1)/2;
		}
		printf("%lld\n",ans);
	}
	return 0;
}

错误原因

没有想到对原式进行变形。

E题

题目大意

一共有 t 组数据,每组数据第一行为 n ,为字符串长度,下一行为一个字符串(只有 ’ . ’ 和 ’ * '字符,每次可以向右或者向左移动 ‘ * ’ 字符,求把所有的 ’ * ’ 字符连起来的最小移动次数。

初次思路

暴力模拟。

正解思路

中间的羊是羊群的中心,因此让羊往中心靠拢最优,所以统计其它羊靠过来的距离最优。

正解代码

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int sheep[1000005];
int main(){
	int t;
	cin>>t;
	while(t--){
		long long n,cnt=0,step=0;
		string s;
		cin>>n>>s;
		for(int i=0;i<n;i++){
			if(s[i]=='*'){
				sheep[++cnt]=i;
			}
		}
		int mid=(1+cnt)/2;
		int len_left=1,len_right=1;
		for(int i=1;i<=cnt;i++){
			if(sheep[mid]>sheep[i]){
				step+=sheep[mid]-sheep[i]-len_left++;
			}
			if(sheep[mid]<sheep[i]){
				step+=sheep[i]-sheep[mid]-len_right++;
			}
		}
		cout<<step<<"\n";
	} 
    return 0;
}

F1题

题目大意

交互题。给定 n,t,k(由于这里是简单版,保证 t=1,即t没啥用),有一个长度为n的标号为1⋯n 的仅含01的数组,你每次可以询问l到r的和,需要得出数组中第k个0的下标。最多询问20次。

正解思路

可以用二分枚举位置,通过询问结果来判断前面有多少个0,如果0的数量大于等于k,说明mid要变小,l=mid+1,反之,r=mid。

正解代码

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int sheep[1000005];
int main(){
	int m,n,t;
	cin>>m>>t>>n;
	int l=1,r=m;
	while(l<r){
		int mid=(l+r)/2;
		cout<<"? "<<1<<" "<<mid<<"\n";
		cout.flush();
		int x;
		cin>>x;
		if(mid-x>=n){
			r=mid;
		}
		else{
			l=mid+1;
		}
	}
	cout<<"! "<<l;
    return 0;
}

G题

题目大意

给定一个n×m的网格,每个格子(i,j)都有一个整数参数 a i j ( − 1 < = a i j < = 1 0 9 ) a_{ij}(-1<=a_{ij}<=10^9) aij(1<=aij<=109), a i j = − 1 a_{ij}=−1 aij=1表示这个格子不能通过;否则,这个格子可以通过,若 a i j > 0 a_{ij}>0 aij>0则表示这个格子内有一个传送门。现在小D想要从(1,1)移动到(n,m),它可以以如下两种方式移动:在任意两个相邻且参数均不为−1的格子间移动,花费为w,在有传送门的两个格子 (i,j)和(x,y) 间移动,花费为 a i j + a x y a_{ij}+a_{xy} aij+axy求小D所需的最小花费。

正解思路

分类思考,一是不走传送门,二是走一次传送门,进行两次bfs,求出最终结果。

正解代码

#include <bits/stdc++.h>
using namespace std;
int n,m,w;
int a[2010][2010],dis[2010][2010];
long long ans1=0x3f3f3f3f3f3f3f3f,ans2=0x3f3f3f3f3f3f3f3f,allans=0x3f3f3f3f3f3f3f3f;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
void bfs(int sx,int sy,long long &ans){
    memset(dis,-1,sizeof(dis));
    queue<pair<int,int> >que;
    dis[sx][sy]=0;
    que.push(make_pair(sx,sy));
    while(!que.empty()){
        int x=que.front().first,y=que.front().second;
        que.pop();
        for(int i=0;i<4;i++){
            int nx=x+dx[i],ny=y+dy[i];
            if(nx<1||ny<1||nx>n||ny>m||a[nx][ny]==-1||dis[nx][ny]!=-1){
            	continue;
			}
            dis[nx][ny]=dis[x][y]+1;
            que.push(make_pair(nx,ny));
        }
    }
    if(sx==1&&dis[n][m]!=-1){
    	allans=min(allans,(long long)dis[n][m]*w);
	}
    for(int i=1;i<=n;i++){
    	for(int j=1;j<=m;j++){
    		if(dis[i][j]!=-1&&a[i][j]>0){
    			ans=min(ans,(long long)dis[i][j]*w+a[i][j]);
			}
		} 
	}
}
int main(){
    scanf("%d%d%d",&n,&m,&w);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            scanf("%d",&a[i][j]);
        }
    }
    bfs(1,1,ans1);
    bfs(n,m,ans2);
    allans=min(allans,ans1+ans2);
    printf("%lld",allans==0x3f3f3f3f3f3f3f3f?-1:allans);
    return 0;
}
  • 31
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Codeforces Round 894 (Div. 3) 是一个Codeforces举办的比赛,是第894轮的Div. 3级别比赛。它包含了一系列题目,其中包括题目E. Kolya and Movie Theatre。 根据题目描述,E. Kolya and Movie Theatre问题要求我们给定两个字符串,通过三种操作来让字符串a等于字符串b。这三种操作分别为:交换a中相同位置的字符、交换a中对称位置的字符、交换b中对称位置的字符。我们需要先进行一次预处理,替换a中的字符,然后进行上述三种操作,最终得到a等于b的结果。我们需要计算预处理操作的次数。 根据引用的讨论,当且仅当b[i]==b[n-i-1]时,如果a[i]!=a[n-i-1],需要进行一次操作;否则不需要操作。所以我们可以遍历字符串b的前半部分,判断对应位置的字符是否与后半部分对称,并统计需要进行操作的次数。 以上就是Codeforces Round 894 (Div. 3)的简要说明和题目E. Kolya and Movie Theatre的要求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Codeforces Round #498 (Div. 3) (A+B+C+D+E+F)](https://blog.csdn.net/qq_46030630/article/details/108804114)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Codeforces Round 894 (Div. 3)A~E题解](https://blog.csdn.net/gyeolhada/article/details/132491891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值