【kickstart】2020 B round

230 篇文章 0 订阅
9 篇文章 0 订阅

比赛链接:https://codingcompetitions.withgoogle.com/kickstart/round/000000000019ffc8

赛后总结

其实有很久没有刷题了,从博客数量可以看出来,但这轮比赛还是去做了,所以4道题只能做出简单的2道半来,水平就那样了...

 

题目

由于时间关系,先只总结前3题了。

1.Bike Tour

Li has planned a bike tour through the mountains of Switzerland. His tour consists of N checkpoints, numbered from 1 to N in the order he will visit them. The i-th checkpoint has a height of Hi.

A checkpoint is a peak if:

  • It is not the 1st checkpoint or the N-th checkpoint, and
  • The height of the checkpoint is strictly greater than the checkpoint immediately before it and the checkpoint immediately after it.

Please help Li find out the number of peaks.

Input

The first line of the input gives the number of test cases, TT test cases follow. Each test case begins with a line containing the integer N. The second line contains N integers. The i-th integer is Hi.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the number of peaks in Li's bike tour.

Limits

Time limit: 10 seconds per test set.
Memory limit: 1GB.
1 ≤ T ≤ 100.
1 ≤ Hi ≤ 100.

Test set 1

3 ≤ N ≤ 5.

Test set 2

3 ≤ N ≤ 100.

Sample

InputOutput
4
3
10 20 14
4
7 7 7 7
5
10 90 20 90 10
3
10 3 10
Case #1: 1
Case #2: 0
Case #3: 2
Case #4: 0

  
  • In sample case #1, the 2nd checkpoint is a peak.
  • In sample case #2, there are no peaks.
  • In sample case #3, the 2nd and 4th checkpoint are peaks.
  • In sample case #4, there are no peaks.

题目链接:https://codingcompetitions.withgoogle.com/kickstart/round/000000000019ffc8/00000000002d82e6

思路

这道题就是模拟即可。时间复杂度O(n),空间复杂度O(1)。

#include <algorithm>
#include <bitset>
#include <climits>
#include <cmath>
#include <iostream>
#include <queue>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
typedef long long ll;

void solve()    // 每个case里的东西
{
    ll t;
    cin >> t;
    vector<ll> h(t);
    for (ll i = 0; i<t; ++i){
        cin>> h[i];
    }
    ll res = 0;
    for(ll i = 1; i<t-1; ++i){
        if(h[i]>h[i-1] && h[i]>h[i+1]){
            ++res;
        }
    }
    cout<<res;
}

int main(){
    int t = 0;
    cin >> t;
    for (int i = 1; i <= t; ++i)
    {
        cout << "Case #" << i << ": ";
        solve();
        if(i != t)
            cout<<endl;
    }
    return 0;
}

 

2.Bus Routes

Bucket is planning to make a very long journey across the countryside by bus. Her journey consists of N bus routes, numbered from 1 to N in the order she must take them. The buses themselves are very fast, but do not run often. The i-th bus route only runs every Xi days.

More specifically, she can only take the i-th bus on day Xi, 2Xi, 3Xi and so on. Since the buses are very fast, she can take multiple buses on the same day.

Bucket must finish her journey by day D, but she would like to start the journey as late as possible. What is the latest day she could take the first bus, and still finish her journey by day D?

It is guaranteed that it is possible for Bucket to finish her journey by day D.

Input

The first line of the input gives the number of test cases, TT test cases follow. Each test case begins with a line containing the two integers N and D. Then, another line follows containing N integers, the i-th one is Xi.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the latest day she could take the first bus, and still finish her journey by day D.

Limits

Time limit: 10 seconds per test set.
Memory limit: 1GB.
1 ≤ T ≤ 100.
1 ≤ Xi ≤ D.
1 ≤ N ≤ 1000.
It is guaranteed that it is possible for Bucket to finish her journey by day D.

Test set 1

1 ≤ D ≤ 100.

Test set 2

1 ≤ D ≤ 1012.

Sample

InputOutput
3
3 10
3 7 2
4 100
11 10 5 50
1 1
1
Case #1: 6
Case #2: 99
Case #3: 1

  

In Sample Case #1, there are N = 3 bus routes and Bucket must arrive by day D = 10. She could:

  • Take the 1st bus on day 6 (X1 = 3),
  • Take the 2nd bus on day 7 (X2 = 7) and
  • Take the 3rd bus on day 8 (X3 = 2).

In Sample Case #2, there are N = 4 bus routes and Bucket must arrive by day D = 100. She could:

  • Take the 1st bus on day 99 (X1 = 11),
  • Take the 2nd bus on day 100 (X2 = 10),
  • Take the 3rd bus on day 100 (X3 = 5) and
  • Take the 4th bus on day 100 (X4 = 50),

In Sample Case #3, there is N = 1 bus route and Bucket must arrive by day D = 1. She could:

  • Take the 1st bus on day 1 (X1 = 1).

题目链接:https://codingcompetitions.withgoogle.com/kickstart/round/000000000019ffc8/00000000002d83bf

思路

这道题需要总结一下规律,同时有多个限制,从最后一个限制开始倒推考虑。

#include <algorithm>
#include <bitset>
#include <climits>
#include <cmath>
#include <iostream>
#include <queue>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
typedef long long ll;

void solve2()    // 每个case里的东西
{
    ll n,d;
    cin >> n>> d;
    vector<ll> x(n);
    for (ll i = 0; i<n; ++i){
        cin>> x[i];
    }
    ll res = d, cur = n-1;
    while(cur>=0){
        res = res - res % x[cur];
        --cur;
    }
    cout<<res;
}

int main(){
    int t = 0;
    cin >> t;
    for (int i = 1; i <= t; ++i)
    {
        cout << "Case #" << i << ": ";
        solve2();
        if(i != t)
            cout<<endl;
    }
    return 0;
}

 

3.Robot Path Decoding

Your country's space agency has just landed a rover on a new planet, which can be thought of as a grid of squares containing 109 columns (numbered starting from 1 from west to east) and 109 rows (numbered starting from 1 from north to south). Let (w, h) denote the square in the w-th column and the h-th row. The rover begins on the square (1, 1).

The rover can be maneuvered around on the surface of the planet by sending it a program, which is a string of characters representing movements in the four cardinal directions. The robot executes each character of the string in order:

  • N: Move one unit north.
  • S: Move one unit south.
  • E: Move one unit east.
  • W: Move one unit west.

There is also a special instruction X(Y), where X is a number between 2 and 9 inclusive and Y is a non-empty subprogram. This denotes that the robot should repeat the subprogram Y a total of X times. For example:

  • 2(NWE) is equivalent to NWENWE.
  • 3(S2(E)) is equivalent to SEESEESEE.
  • EEEE4(N)2(SS) is equivalent to EEEENNNNSSSS.

Since the planet is a torus, the first and last columns are adjacent, so moving east from column 109 will move the rover to column 1 and moving south from row 109 will move the rover to row 1. Similarly, moving west from column 1 will move the rover to column 109 and moving north from row 1 will move the rover to row 109. Given a program that the robot will execute, determine the final position of the robot after it has finished all its movements.

Input

The first line of the input gives the number of test cases, TT lines follow. Each line contains a single string: the program sent to the rover.

Output

For each test case, output one line containing Case #x: w h, where x is the test case number (starting from 1) and w h is the final square (w, h) the rover finishes in.

Limits

Time limit: 10 seconds per test set.
Memory limit: 1GB.
1 ≤ T ≤ 100.
The string represents a valid program.
The length of each program is between 1 and 2000 characters inclusive.

Test set 1

The total number of moves the robot will make in a single test case is at most 104.

Test set 2

No additional constraints.

Sample

InputOutput
4
SSSEEE
N
N3(S)N2(E)N
2(3(NW)2(W2(EE)W))
Case #1: 4 4
Case #2: 1 1000000000
Case #3: 3 1
Case #4: 3 999999995

  

In Sample Case #1, the rover moves three units south, then three units east.

In Sample Case #2, the rover moves one unit north. Since the planet is a torus, this moves it into row 109.

In Sample Case #3, the program given to the rover is equivalent to NSSSNEEN.

In Sample Case #4, the program given to the rover is equivalent to NWNWNWWEEEEWWEEEEWNWNWNWWEEEEWWEEEEW.

题目链接:https://codingcompetitions.withgoogle.com/kickstart/round/000000000019ffc8/00000000002d83dc

思路

这道题只通过了小数据集,总体思路是先用递归讲操作序列平铺展开,然后在模拟操作找得到最后位置。

下面是当时的代码:

//
//  main.cpp
//  ks_0419
//
//  Created by Zheng Xin on 2020/4/19.
//  Copyright © 2020 Zheng Xin. All rights reserved.
//


#include <algorithm>
#include <bitset>
#include <climits>
#include <cmath>
#include <iostream>
#include <queue>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
typedef long long ll;

ll getnum(string s, ll &idx){
    ll res = 0;
    ll i=idx;
    for(; i<s.size();++i){
        if(s[i]=='('){
            break;
        }else{
            res = res * 10 + (s[i] - '0');
        }
    }
    idx = i+1;
    return res;
}

string take(string s, ll &idx){
    ll len = s.size();
    string cmd;

    ll i = idx;
    for (; i<len; ++i){
        if(s[i]==')'){
           break;
        }
        ll cur = s[i]-'0';
        if(cur>=0 && cur<=9){
            cur = getnum(s, i); // i此时指向(
            // 取重复
            string rep = take(s, i);
            for(ll j=0; j<cur; ++j){
                cmd += rep;
            }
        }
        else{
            cmd += s[i];
        }
    }
    idx = i;
    return cmd;
}

void solve3()    // 每个case里的东西
{
    string s;
    cin >> s;
    unordered_map<char,vector<ll>> move;
    move['S']={0,1};
    move['N']={0,-1};
    move['W']={-1,0};
    move['E']={1,0};
    unordered_set<char> dir = {'N','E','S','W'};
    ll idx = 0;
    string cmd = take(s, idx);
    ll line = 1, col = 1;
    for(int i=0;i<cmd.size(); ++i){
        line += move[cmd[i]][0];
        col += move[cmd[i]][1];
        if(line<=0){
            line = 1000000000;
        }else if(line>1000000000){
            line = 1;
        }
        if(col<=0){
            col= 1000000000;
        }else if(col>1000000000){
            col = 1;
        }
    }
    cout<<line<<" "<<col;
}

int main(){
    int t = 0;
    cin >> t;
    for (int i = 1; i <= t; ++i)
    {
        cout << "Case #" << i << ": ";
        solve3();
        if(i != t)
            cout<<endl;
    }
    return 0;
}

官方解答在递归时就直接向上返回各个方向移动大小的统计,然后最后对位置进行加减和处理grid是球状的问题。

根据官方的思路实现一下:

#include <algorithm>
#include <bitset>
#include <climits>
#include <cmath>
#include <iostream>
#include <queue>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
typedef long long ll;

ll getnum(string s, ll &idx){
    ll res = 0;
    ll i=idx;
    for(; i<s.size();++i){
        if(s[i]=='('){
            break;
        }else{
            res = res * 10 + (s[i] - '0');
        }
    }
    idx = i+1;
    return res;
}

unordered_map<char,ll> take1(string s, ll &idx){
    ll len = s.size();
    unordered_map<char, ll> res;
    ll i = idx;
    for (; i<len; ++i){
        if(s[i]==')'){
            break;
        }
        ll cur = s[i]-'0';
        if(cur>=0 && cur<=9){
            cur = getnum(s, i); // i此时指向(
            // 取重复
            auto rep = take1(s, i);
            res['E'] = (res['E'] + rep['E'] * cur) % 1000000000;
            res['S'] = (res['S'] + rep['S'] * cur) % 1000000000;
            res['N'] = (res['N'] + rep['N'] * cur) % 1000000000;
            res['W'] = (res['W'] + rep['W'] * cur) % 1000000000;
        }
        else{
            ++res[s[i]];
        }
    }
    idx = i;
    return res;
}
void solve3()    // 每个case里的东西
{
    string s;
    cin >> s;
    ll idx = 0;
    unordered_map<char,ll> cal = take1(s,idx);
    ll line = 1 + cal['E'] - cal['W'], col = 1 + cal['S'] - cal['N'];
    if(line<=0){
        line = 1000000000 - abs(line) % 1000000000;
    }else if(line>1000000000){
        line = 1 + line % 1000000000;
    }
    if(col<=0){
        col= 1000000000 - abs(col) % 1000000000;
    }else if(col>1000000000){
        col = 1 + col % 1000000000;
    }
    cout<<line<<" "<<col;
}

int main(){
    int t = 0;
    cin >> t;
    for (int i = 1; i <= t; ++i)
    {
        cout << "Case #" << i << ": ";
        solve3();
        if(i != t)
            cout<<endl;
    }
    return 0;
}

!有一个要点:在递归统计的时候,为了防止直接求和数字过大溢出,而变化大小超过grid宽度的 只有超出的部分起到实际移动作用,因此需要进行取余。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值