Loading

AtCoder Beginner Contest 335




B - Tetrahedral Number

难度: ⭐

题目大意

给定一个n, 输出所有可能的三元组(x, y, z) 使得x + y + z <= n;

解题思路

n的数据范围很小, 打个三重循环就行;

神秘代码

#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define endl '\n'
using namespace std;
const int N = 5e5 + 10, mod = 998244353;
typedef pair<int, int> PII;
int n, m, res;
signed main() {
    cin >> n;
    for(int i = 0; i <= n; i++){
        for(int j = 0; j <= n - i; j++){
            for(int k = 0; k <= n - i - j; k++){
                cout << i << ' ' << j << ' ' << k << endl;
            }
        }
    }
    return 0;
}




C - Loong Tracking

难度: ⭐⭐⭐

题目大意

一条龙由n个部分组成; 在一个二维坐标系中, 第i部分位于坐标(i, 0)上; 现在可以进行两种操作, 一是将第一部分, 也就是龙头向某个方向移动一格, 而且后面的部分也会跟着动, 第i部分会移动到第i - 1部分的位置; 第二种操作就是询问某一部分当前的坐标是多少;

解题思路

因为数据范围较大, 所以对于询问我们要用O(1)的复杂度解决; 由于移动的连锁效应, 我们发现龙的每一部分都要完成我们所给的移动指令, 而且每一部分不同的是最开始的时候需要向左移动多少格之后再开始依次完成我们所给的指令; 所以我们可以用前缀和实现我们移动指令所实现的总效应;

神秘代码

#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define endl '\n'
using namespace std;
const int N = 2e5 + 10, mod = 998244353;
typedef pair<int, int> PII;
int n, m, idx;
map<int, PII> mp;
PII p[N], s[N];
signed main() {
    cin >> n >> m;
    for(int i = 1; i <= n; i++){
        mp[i] = {i, 0};
    }
    while(m--){
        int a;
        cin >> a;
        if(a == 1){
            char c;
            cin >> c;
            if(c == 'U') p[++idx] = {0, 1};
            else if(c == 'D') p[++idx] = {0, -1};
            else if(c == 'R') p[++idx] = {1, 0};
            else if(c == 'L') p[++idx] = {-1, 0};
            s[idx].first = s[idx - 1].first + p[idx].first;
            s[idx].second = s[idx - 1].second + p[idx].second;
        }
        else {
            int b;
            cin >> b;
            if(idx < b){
                cout << b - idx << ' ' << 0 << endl;
            }
            else {
                int x = 1 + s[idx - b + 1].first;
                int y = s[idx - b + 1].second;
                cout << x << ' ' << y << endl;
            }
        }
    }
    return 0;
}




D - Loong and Takahashi

难度: ⭐⭐

题目大意

给定一个n*n的方格, n一定为奇数; 其中方格的中心位置输出字符'T'; 现在往这个方格中填充数字1 ~ n2 - 1; 要求x必须位于x - 1相邻的格子中, 也就是上下左右四个方向;

解题思路

不要想的太复杂, 像盘绳子一样一圈一圈的填充即可; 样例已经提示了;

神秘代码

#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define endl '\n'
using namespace std;
const int N = 2e5 + 10, mod = 998244353;
typedef pair<int, int> PII;
int n, m, idx;
int g[50][50];
int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
void dfs(int x, int y, int u, int d){
    if(g[x][y] == -1) return;
    g[x][y] = u;
    int a = x + dx[d], b = y + dy[d];
    if(a >= 1 && a <= n && b >= 1 && b <= n && g[a][b] == 0) {
        x = a, y = b;
    }
    else {
        d = (d + 1) % 4;
        x = x + dx[d], y = y + dy[d];
    }
    dfs(x, y, u + 1, d);
}
signed main() {
    cin >> n;
    g[(n + 1) / 2][(n + 1) / 2] = -1;
    dfs(1, 1, 1, 0);
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            if(g[i][j] < 0) cout << "T ";
            else cout << g[i][j] << ' ';
        }
        cout << endl;
    }
    return 0;
}




E - Non-Decreasing Colorful Path

难度: ⭐⭐⭐⭐

题目大意

给定一个n点m边的无向图; 每个顶点都有一个分数; 对于一条从1到n的简单路径(一个顶点不会经过两次), 设S是沿该路径所得到的数列. 他的分数计算规则是: S如果是一个不递增的数列, 那么其分数是该路径的分数就是S中不同数字的个数; 否则分数就为0;

解题思路

因为给定的是一个无向图, 根据分数的计算可知, 如果想得分, 就必须从分数小的走向分数大于等于它的; 所以在建边时, 只有当a的分数小于等于b时我们才建立一条a指向b的边; 这样我们就得到了一个有向图, 这样就方便了我们后续的计算;
如果a的分数和b的分数相同, 那么就默认边权为0, 否则边权就是1; 并且初始得分为1, 遍历图找1到n的最长路径即可; 要注意dijkstra中堆的排序方式, 优先走分数低的点, 如果分数一样则先走当前累积分数高的点; 这里不能用spfa来做;

神秘代码

#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define endl '\n'
using namespace std;
const int N = 2e5 + 10, mod = 998244353;
typedef pair<int, int> PII;
int n, m, idx;
int p[N], fa[N], dis[N];
bool st[N];
map<int, int> mp;
vector<int> edge[N];
struct Node{
    int u, num;
    bool operator< (const Node &a) const{
        if(p[u] == p[a.u]) return num < a.num;
        else return p[u] > p[a.u];
    }
};
int solve(){
    priority_queue<Node> heap;
    heap.push({1, 1});
    dis[1] = 1;
    while(heap.size()){
        int u = heap.top().u;
        heap.pop();
        if(st[u]) continue;
        st[u] = true;
        for(int i = 0; i < edge[u].size(); i++){
            int j = edge[u][i];
            if(dis[j] < dis[u] + (p[u] < p[j])){
                dis[j] = dis[u] + (p[u] < p[j]);
                heap.push({j, dis[j]});
            }
        }
    }
    return dis[n];
}
signed main() {
    IOS; 
    cin >> n >> m;
    for(int i = 1; i <= n; i++){
        cin >> p[i];
    }
    while(m--){
        int a, b;
        cin >> a >> b;
        if(p[a] <= p[b]) edge[a].push_back(b);
        if(p[b] <= p[a]) edge[b].push_back(a);
    }
    cout << solve();
    return 0;
}




F - Hop Sugoroku

难度: ⭐⭐⭐⭐

posted @ 2024-01-15 16:45  mostimali  阅读(21)  评论(0编辑  收藏  举报