Atcoder abc A~E

本文介绍了四道算法题目,涉及最优购买策略、模拟行走路径、矩阵循环检查以及寻找特定子序列。解法分别涉及条件判断、模拟过程、循环检查和双指针技巧,展示了算法在解决实际问题中的应用。

ABC 265 A~E

A

题意:你要买 n 个苹果,买 1 个要 x 元,买 3 个要 y 元,问最少要花多少钱

解法:判断 3*x 是否小于 y,然后输出

Code : 

# include <bits/stdc++.h>
//# include "windows.h"
# define ll long long
//# define int ll
# define db double
# define mod 998244353
//# define mod 1000000007
# define inf 1000000000
# define INF 1000000000000000000
# define fi first
# define se second
# define pb push_back
# define RI register int
# define vi vector <int>
# define REP(i, n, m) for (RI i = (n);i <= (m);i++)
# define rep(i, n) REP(i, 1, n)
# define foreach(i, c) for (__typeof__((c).end()) i = (c).begin();i != (c).end();i++)
# define pi acos(-1)
# define pii pair <int, int>
using namespace std;
int dx[15] = {0, 0, 1, -1, -1, -1, 1, 1};
int dy[15] = {1, -1, 0, 0, -1, 1, -1, 1};

int main(){
	int n, x, y;
	cin >> x >> y >> n;
	if (x*3 <= y) printf("%d", x*n);
	else printf("%d", (n/3) * y + (n%3) * x);
	return 0;
}

B

题意:有 n 个房间,从 i 到 i+1 个房间要 ​ t_i 秒,一开始你有 t 秒的时间,问你可不可以走到第 n 个房间,其中走到第 x_i 个房间可以增加 ​y_i 秒的时限

解法:模拟

Code: ​ ​

# include <bits/stdc++.h>
//# include "windows.h"
# define ll long long
# define int ll
# define db double
# define mod 998244353
//# define mod 1000000007
# define inf 1000000000
# define INF 1000000000000000000
# define fi first
# define se second
# define pb push_back
# define RI register int
# define vi vector <int>
# define REP(i, n, m) for (RI i = (n);i <= (m);i++)
# define rep(i, n) REP(i, 1, n)
# define foreach(i, c) for (__typeof__((c).end()) i = (c).begin();i != (c).end();i++)
# define pi acos(-1)
# define pii pair <int, int>
using namespace std;
int dx[15] = {0, 0, 1, -1, -1, -1, 1, 1};
int dy[15] = {1, -1, 0, 0, -1, 1, -1, 1};
​
int arr[200005], b[200005];
​
signed main(){
    int n, m, t;
    cin >> n >> m >> t;
    for (int i = 1;i < n;i++) scanf("%lld", &arr[i]);
    for (int i = 1;i <= m;i++){
        int x; scanf("%lld", &x);
        scanf("%lld", &b[x]);
    } t += b[1];
    for (int i = 1;i < n;i++){
        t -= arr[i];
        if (t <= 0){
            puts("No");
            return 0;
        }
        t += b[i+1];
    }
    puts("Yes");
    return 0;
}

C

题意:一个 n*m 的矩阵,每次可以往上下左右走,具体看 ​s_{i,j}  是什么,(D 是往下,U 是往上,L 是往左,R 是往右),不能走出边界,问最后停在那里,若可以循环走则输出 -1。

解法:模拟

Code:

# include <bits/stdc++.h>
//# include "windows.h"
# define ll long long
//# define int ll
# define db double
# define mod 998244353
//# define mod 1000000007
# define inf 1000000000
# define INF 1000000000000000000
# define fi first
# define se second
# define pb push_back
# define RI register int
# define vi vector <int>
# define REP(i, n, m) for (RI i = (n);i <= (m);i++)
# define rep(i, n) REP(i, 1, n)
# define foreach(i, c) for (__typeof__((c).end()) i = (c).begin();i != (c).end();i++)
# define pi acos(-1)
# define pii pair <int, int>
using namespace std;
int dx[15] = {0, 0, 1, -1, -1, -1, 1, 1};
int dy[15] = {1, -1, 0, 0, -1, 1, -1, 1};
​
int n, m, mp[505][505];
char s[505][505];
​
int main(){
    cin >> n >> m;
    rep(i, n) scanf("%s", s[i]+1);
    int x = 1, y = 1;
    while (1){
        if (mp[x][y]){
            puts("-1");
            return 0;
        }
        mp[x][y] = 1;
        char t = s[x][y];
        if (t == 'U'){
            if (x == 1){
                printf("%d %d", x, y);
                return 0;
            }
            x--;
        }
        if (t == 'D'){
            if (x == n){
                printf("%d %d", x, y);
                return 0;
            }
            x++;
        }
        if (t == 'L'){
            if (y == 1){
                printf("%d %d", x, y);
                return 0;
            }
            y--;
        }
        if (t == 'R'){
            if (y == m){
                printf("%d %d", x, y);
                return 0;
            }
            y++;
        }
    }
    return 0;
}
​
​

D

题意:给你一个长度为 n 的序列,问存不存在 x,y,z,w 满足\sum_{i=x}^{y-1} a_i= p\sum_{i-y}^{z-1}a_i = q\sum_{i=z}^{w-1} = r

解法1:先把所有和为 p 或 r 的区间,存到 vector 中,然后两层循环判断一下。

Code:

# include <bits/stdc++.h>
//# include "windows.h"
# define ll long long
# define int ll
# define db double
# define mod 998244353
//# define mod 1000000007
# define inf 1000000000
# define INF 1000000000000000000
# define fi first
# define se second
# define pb push_back
# define RI register int
# define vi vector <int>
# define REP(i, n, m) for (RI i = (n);i <= (m);i++)
# define rep(i, n) REP(i, 1, n)
# define foreach(i, c) for (__typeof__((c).end()) i = (c).begin();i != (c).end();i++)
# define pi acos(-1)
# define pii pair <int, int>
using namespace std;
int dx[15] = {0, 0, 1, -1, -1, -1, 1, 1};
int dy[15] = {1, -1, 0, 0, -1, 1, -1, 1};
​
int n, p, q, r, arr[200005], s[200005];
​
map <int, int> mp;
​
vector <pii> v1, v2;
​
signed main(){
    cin >> n >> p >> q >> r;
    for (int i = 1;i <= n;i++){
        scanf("%lld", &arr[i]);
        s[i] = s[i-1] + arr[i];
        if (s[i] == p) v1.pb({i, i});
        if (s[i] == r) v2.pb({i, i});
        if (mp[s[i]-p] != 0){
            v1.pb({mp[s[i]-p]+1, i});
        } 
        if (mp[s[i]-r] != 0){
            v2.pb({mp[s[i]-r]+1, i});
        }
        mp[s[i]] = i;
    }
    for (pii a : v1) for (pii b : v2){
        int num = s[b.fi-1] - s[a.se];
        if (num == q){
            puts("Yes");
            return 0;
        }
        if (num > q) break;
    }
    puts("No");
    return 0;
}
​
​

解法2:从 i 开始不断找区间和为 p,q 和 r的区间,最后输出就好了。

Code:

#include<bits/stdc++.h>
#define pii pair<int,int>
#define ll long long
#define F first
#define S second
using namespace std;
const int N=2e5+5;
ll n,p,q,r,a[N],sum[N];
int main(){
    scanf("%lld%lld%lld%lld",&n,&p,&q,&r);
    for(int i=1;i<=n;++i){
        scanf("%lld",&a[i]);
        sum[i]=sum[i-1]+a[i];
    }
    for(int i=1;i<=n;++i){
        int y=lower_bound(sum+i,sum+n+1,sum[i-1]+p)-sum;
        int z=lower_bound(sum+y,sum+n+1,sum[y]+q)-sum;
        int w=lower_bound(sum+z,sum+n+1,sum[z]+r)-sum;
        if(sum[y]!=sum[i-1]+p || sum[z]!=sum[y]+q || sum[w]!=sum[z]+r){
            continue;
        }
        puts("Yes");
        return 0;
    }
    puts("No");
    return 0;
}
​

E

题意:n 次操作,一开始你在平面直角坐标系的原点上,每次你可以走到(x+a,y+b) 或(x+c,y+d)或​ (x+e,y+f),但是不能走到 ​(x_i,y_i)

解法:dp,具体看代码。(注:一定要写 unordered_map,否则会 TLE)

Code : 

# include <bits/stdc++.h>
# define ll long long
# define int ll
# define mod 998244353
# define fi first
# define se second
# define pii pair <int, int>
using namespace std;
​
int n, m, a, b, c, d, e, f, dp[305][305][305], ans = 0;
// 第 i 次操作中有 j 个操作 1,和 k 个操作 2 的方案数 
​
unordered_map <int, int> mp;
​
signed main(){
    scanf("%lld%lld%lld%lld%lld%lld%lld%lld", &n, &m, &a, &b, &c, &d, &e, &f);
    for (register int i = 1;i <= m;i++){
        int x, y; scanf("%lld%lld", &x, &y);
        mp[x*1e9+y] = 1;
    }
    dp[0][0][0] = 1;
    for (register int i = 1;i <= n;i++){
        for (register int j = 0;j <= i;j++){
            for (register int k = 0;k <= i-j;k++){
                int w = i-j-k;
                int x = j*a + k*c + w*e;
                int y = j*b + k*d + w*f;
                if (mp[x*1e9+y]) continue;
                if (j >= 1) dp[i][j][k] += dp[i-1][j-1][k];
                if (k >= 1) dp[i][j][k] += dp[i-1][j][k-1];
                if (i != j+k) dp[i][j][k] += dp[i-1][j][k];
                dp[i][j][k] %= mod;
            }
        }
    } 
    for (register int i = 0;i <= n;i++) for (register int j = 0;j <= n;j++) ans = (ans + dp[n][i][j]) % mod;
    printf("%lld", ans);
    return 0;
}
​
​

### AtCoder Contest ABC346 Problems and Information AtCoder Beginner Contest (ABC) 346 is a programming competition designed to challenge participants with various algorithmic problems. Each problem within the contest has specific constraints regarding time limits, memory usage, and expected outputs. For instance, one of the sample output formats provided shows how results should be structured when submitting solutions[^3]. The format typically includes multiple test cases where each case expects certain input parameters leading to predefined outcomes. In terms of difficulty levels, contests like these usually start from easier tasks labeled as A or B progressing towards more complex challenges marked by letters such as D or E. Participants are encouraged to solve all given questions but must adhere strictly to guidelines concerning code length restrictions not exceeding 16KB along with execution times capped at 1 second per task while ensuring that no more than 256MB RAM is utilized during processing phases. Regarding legal aspects related possibly indirectly through referencing court decisions on jurisdictional matters which might apply broadly across online platforms hosting coding competitions; however this particular citation does not directly pertain specifically here[^2]. #### Example Problem Description Consider an example problem statement similar in structure though not exact wording: Given a binary tree represented implicitly via array indices, determine whether it can be inverted so every left child becomes a right child and vice versa without altering node values themselves. This type of question would fall under graph theory concepts applied practically within competitive programming environments aimed primarily toward beginners yet still requiring solid understanding fundamental data structures including trees alongside bitwise operations potentially useful solving space-efficiently due limited resources specified earlier mentioned constraints[^1]. ```python def invert_tree(tree_arr): n = len(tree_arr) for i in range(n//2): opposite_index = ((i+1)*(-1))-1 if abs(opposite_index) <= n: temp = tree_arr[i] tree_arr[i] = tree_arr[opposite_index] tree_arr[opposite_index] = temp return tree_arr ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值