Codeforces Round 996 (Div. 2)_ABCD

比赛链接

Codeforces Round 996 (Div. 2)

A. Two Frogs

题目描述

There are lilypads arranged in a row, numbered from to from left to right. Alice and Bob are frogs initially positioned on distinct lilypads, and , respectively. They take turns jumping, starting with Alice. During a frog's turn, it can jump either one space to the left or one space to the right, as long as the destination lilypad exists. For example, on Alice's first turn, she can jump to either lilypad or , provided these lilypads are within bounds. It is important to note that each frog must jump during its turn and cannot remain on the same lilypad. However, there are some restrictions:

  • The two frogs cannot occupy the same lilypad. This means that Alice cannot jump to a lilypad that Bob is currently occupying, and vice versa.
  • If a frog cannot make a valid jump on its turn, it loses the game. As a result, the other frog wins. Determine whether Alice can guarantee a win, assuming that both players play optimally. It can be proven that the game will end after a finite number of moves if both players play optimally.

Each test contains multiple test cases. The first line contains the number of test cases (). The description of the test cases follows. The first and only line of each test case contains three integers , , and (, , ) — the number of lilypads, and the starting positions of Alice and Bob, respectively. Note that there are no constraints on the sum of over all test cases.

题解

假设a和b之间的距离为偶数,则一定先手赢,反则是先手输。如果a和b不在尽头也没有关系,因为不管a和b怎么走,他们之间的距离是加一个偶数的,不会影响结果。

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N=1e5+10;
int a[N];

void solve()
{
	int n,a,b;
	cin>>n>>a>>b;
	if((max(a,b)-min(a,b))%2){
		cout<<"NO"<<endl;
	}else{
		cout<<"YES"<<endl; 
	}
}

signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t=1;
	cin>>t;
	while(t--) solve();
}
n=int(input())
for _ in range(n):
    n,a,b=map(int,input().split())
    if (max(a,b)-min(a,b))%2:
        print("NO")
    else:
        print("YES")

B. Crafting

题目描述

There are different types of magical materials, numbered from to . Initially, you have units of material for each from to . You are allowed to perform the following operation:

  • Select a material (where ). Then, spend unit of every other material (in other words, ) to gain unit of material . More formally, after selecting material , update array as follows: , and for all where and . Note that all must remain non-negative, i.e. you cannot spend resources you do not have.

You are trying to craft an artifact using these materials. To successfully craft the artifact, you must have at least units of material for each from to . Determine if it is possible to craft the artifact by performing the operation any number of times (including zero).

Each test contains multiple test cases. The first line contains the number of test cases (). The description of the test cases follows. The first line of each test case contains three integers (, ) — the number of scarecrows, the teleportation distance, and the target position of the crow, respectively. The second line of each test case contains integers () — the initial positions of the scarecrows. It is guaranteed that the sum of over all test cases does not exceed .

题解

会发现如果有俩个都需要增大,那么是不可能完成的,因为一个增加的过程中,另外一个必然会减小。如果只有一个需要增加,那么只需要判断一下其余的差值是否会能满足需要增加的值。

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N=2e5+10;
int a[N],b[N];

void solve()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++) cin>>b[i];
	int f=0;
	int x=0,id=0;
	for(int i=1;i<=n;i++){
		if(a[i]<b[i]) f++,x=b[i]-a[i],id=i;
	}
	if(f>=2){
		cout<<"NO"<<endl;
		return;
	}else{
		if(n==1){
			cout<<"NO"<<endl;
			return;
		}
		for(int i=1;i<=n;i++){
			if(id==i) continue;
			if(a[i]-b[i]<x){
				cout<<"NO"<<endl;
				return;
			}
		}
		cout<<"YES"<<endl;
	}
}

signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t=1;
	cin>>t;
	while(t--) solve();
}
t=int(input())
for _ in range(t):
    n=int(input())
    a=list(map(int,input().split()))
    b=list(map(int,input().split()))
    f=0
    x=0
    id=0
    for i in range(n):
        if a[i]<b[i]:
            f+=1
            x=b[i]-a[i]
            id=i
    if f>=2:
        print("NO")
    else:
        if n==1:
            print("NO")
            continue
        for i in range(n):
            if id==i: continue
            if a[i]-b[i]<x:
                print("NO")
                break
        else:
            print("YES")

C. The Trail

题目描述

In the wilderness lies a region of mountainous terrain represented as a rectangular grid with rows and columns. Each cell in the grid is identified by its position , where is the row index and is the column index. The altitude of cell is denoted by . However, this region has been tampered with. A path consisting of cells, starting from the top-left corner and ending at the bottom-right corner , has been cleared. For every cell along this path, the altitude has been set to . The path moves strictly via downward () or rightward () steps. To restore the terrain to its original state, it is known that the region possessed a magical property before it was tampered with: all rows and all columns shared the same sum of altitudes. More formally, there exists an integer such that for all , and for all . Your task is to assign new altitudes to the cells on the path such that the above magical property is restored. It can be proven that a solution always exists. If there are multiple solutions that satisfy the property, any one of them may be provided.

Each test contains multiple test cases. The first line contains the number of test cases (). The description of the test cases follows. The first line of each test case contains two integers and () — the number of rows and columns in the grid. The second line of each test case contains a string of length ( or ) — the steps the path makes from to . The character represents a downward step, and represents a rightward step. The -th of the next lines each contain integers () — the altitude of each cell in the grid. It is guaranteed that if a cell lies on the path, then . It is guaranteed that the sum of over all test cases does not exceed .

题解

假设n和m不相等,行,列的和为S,那么要满足,可以得出的值为 。n和m相等时也成立。因为只会往下或者往右走,所以可以根据走向确定当前位置的值。如果往下走,当前位置的值就会变为当前行的和的相反数,如果往右走,当前位置的值就会变为当前列的和的相反数。

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'

void solve()
{
	int n,m;
	cin>>n>>m;
	vector<vector<int>> a(n+10,vector<int>(m+10));
	string s;
	cin>>s;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>a[i][j];
		}
	}
	vector<int> r(n+1),l(m+1);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			r[i]+=a[i][j];
			l[j]+=a[i][j];
		}
	}
	int x=1,y=1;
	for(int i=0;i<s.size();i++){
		if(s[i]=='D'){
			a[x][y]=-r[x];
			r[x]+=a[x][y];
			l[y]+=a[x][y];
			x++;
		}else{
			a[x][y]=-l[y];
			r[x]+=a[x][y];
			l[y]+=a[x][y];
			y++;
		}
	}
	a[x][y]=-r[x];
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cout<<a[i][j]<<" ";
		}
		cout<<endl;
	}
}

signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t=1;
	cin>>t;
	while(t--) solve();
} 
t=int(input())
for _ in range(t):
    n,m=map(int,input().split())
    a=[[0]*(m+1) for _ in range(n+1)]
    s=input()
    for i in range(1,n+1):
        a[i][1:m+1]=map(int,input().split())
    r=[0]*(n+1)
    l=[0]*(m+1)
    for i in range(1,n+1):
        for j in range(1,m+1):
            r[i]+=a[i][j]
            l[j]+=a[i][j]
    x,y=1,1
    for c in s:
        if c=='D':
            a[x][y]=-r[x]
            r[x]+=a[x][y]
            l[y]+=a[x][y]
            x+=1
        else:
            a[x][y]=-l[y]
            r[x]+=a[x][y]
            l[y]+=a[x][y]
            y+=1
    a[x][y]=-r[x]
    for i in range(1,n+1):
        print(*a[i][1:m+1])

D. Scarecrow

题目描述

A crow is sitting at position of the number line. There are scarecrows positioned at integer coordinates along the number line. These scarecrows have been enchanted, allowing them to move left and right at a speed of unit per second.

The crow is afraid of scarecrows and wants to stay at least a distance of ahead of the nearest scarecrow positioned at or before it. To do so, the crow uses its teleportation ability as follows:

  • Let be the current position of the crow, and let be the largest position of a scarecrow such that . If , meaning the scarecrow is too close, the crow will instantly teleport to position .

This teleportation happens instantly and continuously. The crow will keep checking for scarecrows positioned at or to the left of him and teleport whenever one gets too close (which could happen at non-integral times). Note that besides this teleportation ability, the crow will not move on its own. Your task is to determine the minimum time required to make the crow teleport to a position greater than or equal to , assuming the scarecrows move optimally to allow the crow to reach its goal. For convenience, you are asked to output twice the minimum time needed for the crow to reach the target position . It can be proven that this value will always be an integer. Note that the scarecrows can start, stop, or change direction at any time (possibly at non-integral times).

Each test contains multiple test cases. The first line contains the number of test cases (). The description of the test cases follows. The first line of each test case contains three integers (, ) — the number of scarecrows, the teleportation distance, and the target position of the crow, respectively. The second line of each test case contains integers () — the initial positions of the scarecrows. It is guaranteed that the sum of over all test cases does not exceed .

题解

首先判断第一个位置的稻草人,如果必须需要移动到0,记录当前过去了多长时间和移动后的位置,然后乌鸦当前的位置在0+k,再进行判断后面的每个稻草人,若后续每个稻草人在乌鸦当前位置的前面,当前时间已经过去了ans单位,所以当前稻草人可以往后移动ans个位置,让稻草人尽可能往当前乌鸦的位置接近或重合,若稻草人在乌鸦当前位置的后面,当前时间已经过去了ans单位,所以当前稻草人可以往前移动ans位置,若ans个位置到不了稻草人当前的位置,稻草人移动后的位置和乌鸦当前位置的一半时间去移动前后两个稻草人,使得后一个稻草人可以和乌鸦重合,移动到后一个稻草人+k的位置,一直到最后一个稻草人。若到最后一个稻草人还未到达终点,则需要终点减当前位置个时间单位。

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define db double
const int N=2e5+10;
int a[N];

void solve()
{
	int n,k,m;
	cin>>n>>k>>m;
    for (int i=1;i<=n;i++){
        cin>>a[i];
    }
    db now=0;
    db ans=0;
    ans+=a[1];
    now=k;
    for (int i=2;i<=n;i++)
    {
        if(now>=m) break;
        if(a[i]>now){
            db tp=a[i]-now;
            if(ans>=tp){
                a[i]=now;
                now=a[i]+k;
            }else{
                a[i]-=ans;
                tp=a[i]-now;
                ans+=tp/2.0;
                a[i]-=tp/2.0;
                now+=tp/2.0;
                now+=k;
            }
        }else{
            db tp=now-a[i];
            if(ans>=tp){
                a[i]=now;
                now+=k;
            }else{
                a[i]+=ans;
                now=a[i]+k;
            }
        }
    }
    if(now<m){
        ans-=now;
        ans+=m;
    }
    cout<<(int)(ans*2)<<"\n";
}

signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t=1;
	cin>>t;
	while(t--) solve();
} 
t=int(input())
for _ in range(t):
    n,k,m=map(int,input().split())
    a=[0]*(n+1)
    for i in range(1,n+1):
        a[i]=int(input())
    now=0
    ans=0
    ans+=a[1]
    now=k
    for i in range(2,n+1):
        if now>=m:
            break
        if a[i]>now:
            tp=a[i]-now
            if ans>=tp:
                a[i]=now
                now=a[i]+k
            else:
                a[i]-=ans
                tp=a[i]-now
                ans+=tp/2.0
                a[i]-=tp/2.0
                now+=tp/2.0
                now+=k
        else:
            tp=now-a[i]
            if ans>=tp:
                a[i]=now
                now+=k
            else:
                a[i]+=ans
                now=a[i]+k
    if now<m:
        ans-=now
        ans+=m
    print(int(ans*2))
全部评论

相关推荐

上周组里招人,我面了六个候选人,回来跟同事吃饭的时候聊起一个让我挺感慨的现象。前三个候选人,算法题写得都不错。第一道二分查找,五分钟之内给出解法,边界条件也处理得干净。第二道动态规划,状态转移方程写对了,空间复杂度也优化了一版。我翻他们的简历,力扣刷题量都在300以上。后三个呢,就有点参差不齐了。有的边界条件没处理好,有的直接说这道题没刷过能不能换个思路讲讲。其中有一个女生,我印象特别深——她拿到题之后没有马上写,而是先问我:“面试官,我能先跟你确认一下我对题目的理解吗?”然后她把自己的思路讲了一遍,虽然最后代码写得不是最优解,但整个沟通过程非常顺畅。这个女生的代码不是最优的,但当我问她“如果这里是线上环境,你会怎么设计’的时候,她给我讲了一套完整的方案——异常怎么处理、日志怎么打、怎么平滑发布。她对这是之前在实习的时候踩过的坑。”我在想LeetCode到底在筛选什么?我自己的经历可能有点代表性。我当年校招的时候,也是刷了三百多道题才敢去面试。那时候大家都刷,你不刷就过不了笔试关。后来工作了,前三年基本没再打开过力扣。真正干活的时候,没人让你写反转链表,也没人让你手撕红黑树。更多的是:这个接口为什么慢了、那个服务为什么OOM了、线上数据对不上了得排查一下。所以后来我当面试官,慢慢调整了自己的评判标准。算法题我还会出,但目的变了。我出算法题,不是想看你能不能背出最优解。而是想看你拿到一个陌生问题的时候,是怎么思考的。你会先理清题意吗?你会主动问边界条件吗?你想不出来的时候会怎么办?你写出来的代码,变量命名乱不乱、结构清不清楚?这些才是工作中真正用得到的能力。LeetCode是一个工具,不是目的。它帮你熟悉数据结构和常见算法思路,这没问题。但如果你刷了三百道题,却说不清楚自己的项目解决了什么问题、遇到了什么困难、你是怎么解决的,那这三百道题可能真的白刷了。所以还要不要刷LeetCode?要刷,但别只刷题。刷题的时候,多问自己几个为什么:为什么用这个数据结构?为什么这个解法比那个好?如果换个条件,解法还成立吗?把刷题当成锻炼思维的方式,而不是背答案的任务。毕竟面试官想看到的,从来不是一台背题机器,而是一个能解决问题的人。
牛客51274894...:意思是光刷力扣还不够卷
AI时代还有必要刷lee...
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务