Codeforces Round 719 (Div. 3) C~F1 G补题报告

参赛者在比赛中遇到的四个题目分别围绕矩阵构造避免相邻数、序列中相同差值计数、调整序列中的星号字符和解决网格中的最小移动与路径问题。展示了如何利用简单的编程技巧解决这些技术挑战。
摘要由CSDN通过智能技术生成

比赛链接

一、概况

比赛名称:Codeforces Round 719 (Div. 3)
日期:2024/3/3
题非常简单,但只做出两个……
把一些简单的题想复杂了,最终没做出来。

二、正解

C. Not Adjacent Matrix

1 题目描述

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

2 大体思路

有许多中构造方式,最简单的:先打印所有奇数,后打印所有偶数(范围内)。

3 AC代码

#include<bits/stdc++.h>
#define ll long long
#define bug printf("---OK---")
#define pa printf("A: ")
#define pr printf("\n")
#define pi acos(-1.0)
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
int main(){
	ll t;
	cin>>t;
	while(t--){
		ll n;
		cin>>n;
		if(n==1){
			cout<<1;pr;
		}
		else if(n==2){
			cout<<-1;pr;
		}
		else{
			ll x=1;
			for(int i=1;i<=n;i++){
				for(int j=1;j<=n;j++){
					cout<<x<<" ";x+=2;
					if(x>n*n){
						x=2;
					}
				}
				pr;
			}
		}
	}
  return 0;
}

D. Same Differences

1 题目描述

给出 T T T 组序列 a a a,长度为 N N 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

2 大体思路

改写一下原题的等式:
a j − j = a i − i a_j - j = a_i - i ajj=aii
把每个 a i a_i ai 换成 b i = a i − i b_i = a_i - i bi=aii 答案就变成了求 ( i , j ) (i,j) (i,j) 中有多少对 i < j i \lt j i<j b i = b j b_i = b_j bi=bj

3 AC代码

#include<bits/stdc++.h>
#define ll long long
#define bug printf("---OK---")
#define pa printf("A: ")
#define pr printf("\n")
#define pi acos(-1.0)
#define INF 0x3f3f3f3f3f3f3f3f
#pragma GCC optimize(2)
using namespace std;
int main(){
	ll t;
	cin>>t;
	while(t--){
	    ll n,ans=0;
	    cin>>n;
	    map<ll,ll> ma;
	    for(int i=0;i<n;i++){
		    ll x;
		    cin>>x;
		    x-=i;
		    ans+=ma[x];
		    ma[x]++;
	    }
	    cout<<ans;pr;
	}
  return 0;
}

E. Arranging The Sheep

1 题目描述

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

2 大体思路

回想一下,你上体育课的时候老师是不是让你向中间的学生靠拢?因为这样移动距离最短。同理,我们让所有 * 都向最中间的 *移动。

3 AC代码

#include<bits/stdc++.h>
#define ll long long
#define bug printf("---OK---")
#define pa printf("A: ")
#define pr printf("\n")
#define pi acos(-1.0)
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
string s;
ll n,m[1000005],top,flag,ans,t;
int main(){
	cin>>t;
	while(t--){
		top=0,flag=0,ans=0;
		cin>>n>>s;
		for(int i=0;i<n;i++){
			if(s[i]=='*'){
				m[++top]=i+1;
			}
			else{
				flag=1;
			}
		}
		if(top==0||top==1||flag==0){
			cout<<0;pr;continue;
		}
		ll mid=top/2+1;
		for(int i=1;i<=top;i++){
			ans+=abs(m[mid]-m[i])-abs(mid-i);
		}
		cout<<ans;pr;
	}
	return 0;
}

F1. Guess the K-th Zero (Easy version)

1 题目描述

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

2 大体思路

二分
假设当前的线段是 [ l , r ] [l, r] [l,r] ,我们想在它上面找到 k k k -th zero。查询 [ l , m ] [l, m] [l,m] 段的一半,即 m = l + r 2 m = \frac{l+r}{2} m=2l+r
如果左半段至少有 k k k 个0,那么我们就去左半段寻找 k k k 个0。如果左半边只有 x < k x \lt k x<k 个0,那么我们就去右边的线段寻找 ( k − x ) (k-x) (kx) 个0。

3 AC代码

#include<bits/stdc++.h>
#define ll long long
#define bug printf("---OK---")
#define pa printf("A: ")
#define pr printf("\n")
#define pi acos(-1.0)
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
void check(ll l,ll r,ll k){
    if(l==r){
        cout<<"! "<<l<<endl;
        return;
    }
    ll m=(l+r)/2;
    cout<<"? "<<l<<" "<<m<<endl;
    ll sum;
    cin>>sum;
    if((m-l+1)-sum>=k){
        check(l,m,k);
    }
	else{
        check(m+1,r,k-(m-l+1)+sum);
    }
}
int main(){
    ll n,t,k;
    cin>>n>>t>>k;
    check(1,n,k);
}

G. To Go Or Not To Go?

1 题目描述

给定一个 n × m n\times{m} n×m 的网格,每个格子 ( i , j ) (i,j) (i,j) 都有一个整数参数 a i j ( − 1 ≤ a i j ≤ 1 0 9 ) a_{ij}(-1\leq a_{ij}\leq10^9) aij(1aij109) a i j = − 1 a_{ij}=-1 aij=1 表示这个格子不能通过;否则,这个格子可以通过,若 a i j > 0 a_{ij}>0 aij>0 则表示这个格子内有一个传送门。
现在小D想要从 ( 1 , 1 ) (1,1) (1,1) 移动到到 ( n , m ) (n,m) (n,m) ,它可以以如下两种方式移动:

  • 在任意两个相邻且参数均不为 − 1 -1 1的格子间移动,花费为 w w w
  • 在有传送门的两个格子 ( i , j ) (i,j) (i,j) ( x , y ) (x,y) (x,y) 间移动,花费为 a i j + a x y a_{ij}+a_{xy} aij+axy

求小D所需的最小花费。

2 大体思路

在传送门之间使用两次转换是没有意义的,因为如果从传送门 A A A 到传送门 B B B ,然后从传送门 B B B 到传送门 C C C ,那么不如从传送门 A A A 转到传送门 C C C ,这样花费更少。
那么就有两条可能的路径。
第一种–不使用传送门。这里只需找到两点之间的最短路径即可。
第二种–使用单一传送门。显然,这个传送门的距离和转换成本都是最小的。

  • 15
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值