首页 > 其他分享 >AtCoder Beginner Contest(abc) 296

AtCoder Beginner Contest(abc) 296

时间:2023-11-18 19:12:18浏览次数:37  
标签:AtCoder abc int Bi long Ai 296 tie define




B - Chessboard

难度: ⭐

题目大意

给定一个8*8的字符矩阵, 其中只有一个' * ', 输出它的坐标; 其坐标的列用字母表示, 行用数字表示, 具体看样例解释;

解题思路

签到题不多嗦了;

神秘代码

#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 = 2e3 + 10;
typedef pair<int, int> PII;
int n, m;
signed main(){
    for(int i = 1; i <= 8; i++){
        string s;
        cin >> s;
        for(int j = 0; j < 8; j++){
            if(s[j] == '*'){
                printf("%c%d", 'a' + j, 8 - i + 1);
                return 0;
            }
        }
    }
    return 0;
}




C - Gap Existence

难度: ⭐⭐

题目大意

给定n个数和一个X, 问这n个数中是否存在两个数Ai和Aj, 使得Ai - Aj = X; 其中i和j可能相等;

解题思路

先记录一下这n个数都有谁, 然后遍历这n个数作为Ai, 再根据X得到对应的Aj, 看看这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 = 2e5 + 10;
typedef pair<int, int> PII;
int n, m;
int f[N];
map<int, int> mp;
signed main(){
    cin >> n >> m;
    for(int i = 1; i <= n; i++){
        cin >> f[i];
        mp[f[i]]++;
    }
    for(int i = 1; i <= n; i++){
        int x = m + f[i];
        if(mp[x]){
            cout << "Yes";
            return 0;
        }
    }
    cout << "No";
    return 0;
}




D - M<=ab

难度: ⭐⭐⭐

题目大意

给定N和M, 要求找到一个数Q, Q是a和b的乘积; a和b是1~N中的两个数(a和b可能相同); 而且Q要求大于等于M; 请问Q最小的值是多少, 如果不存在则输出-1;

解题思路

因为N和M的数据范围很大, 所有考虑二分来找; 我们设x = sqrt(M)为界限, 如果a和b都大于x, 那么得到的Q一定是满足条件的, 但不一定是最小的; 所以我们考虑让a <= x, b >= x; 可以遍历a, 然后用二分来求最小满足条件的b; 但是如果这样没找到的话就只好让a和b都大于x了; 当然a和b的前提都是小于等于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 = 2e5 + 10;
typedef pair<int, int> PII;
int n, m, minn = 1e18 + 10;
signed main(){
    cin >> n >> m;
    int i;
    for(i = 1; i * i <= m; i++){
        if(i > n) break;
        int l = m / i , r = n;
        while(l < r){
            int mid = l + r >> 1;
            int idx = i * mid;
            if(idx >= m) r = mid;
            else l = mid + 1;
        }
        int res = i * l;
        if(res >= m && l <= n){
            minn = min(res, minn);
        }
    }
    if(minn == 1e18 + 10) {
        if(i <= n) {
            int res = i * i;
            cout <<res;
        }
        else cout << -1;
    }
    else cout << minn;
    return 0;
}




E - Transition Game

难度: ⭐⭐⭐

题目大意

给定n个数Ai; 小莫和安姐要进行n回合游戏; 第i回合安姐随机说一个数k, 小莫则从1~n中也挑选一个数s, 并把s写到黑板上, 然后把以下操作重复k次: 如果此时黑板上的数为x, 那么把x替换为Ax;(所有A的大小都是1 ~ n) 如果重复k次后黑板上的数是i, 那么本回合小莫赢, 否则安姐赢; 问小莫可以赢几次;

解题思路

因为k是可以无限大的, 所以如果小莫想要保证第i回合可以赢的话就得让i出现在一个环中, 无论k有多大, 我们只要根据k和环的大小来确定好起点, 那么就可以让k次后恰好轮到i这个数; 因此我们可以用拓扑排序来找出所有不在环中的数x; 第x回合是一定赢不了, 因为k无限大; 反之则一定赢;

神秘代码

#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;
typedef pair<int, int> PII;
int n, m;
int f[N], d[N];
int bfs(){
    queue<int> q;
    for(int i = 1; i <= n; i++){
        if(!d[i]) q.push(i);
    }
    int res = 0;
    while(q.size()){
        int t = q.front();
        q.pop();
        res++;
        d[f[t]]--;
        if(!d[f[t]]){
            q.push(f[t]);
        }
    }
    return n - res;
}
signed main(){
    cin >> n;
    for(int i = 1; i <= n; i++){
        cin >> f[i];
        d[f[i]]++;
    }
    cout << bfs();
    return 0;
}




F - Simultaneous Swap

难度: ⭐⭐⭐⭐

题目大意

给定两个长度为n的数组A和B; 我们每次可以选择一个三元组(i, j, k), 然后让Ai和Aj互换, 让Bi和Bk互换; 请问最后是否可以让数组A和B相同;

解题思路

如果同时改变两个数组那么是很难去讨论的, 所以要考虑看能不能在让数组A不变的情况下改变B; 这样的话可以进行两次操作: 第一次: (Ai, Aj, Ak) -> (Ak, Aj, Ai), (Bi, Bj, Bk) -> (Bj, Bi, Bk); 第二次: (Ak, Aj, Ai) -> (Ai, Aj, Ak), (Bj, Bi, Bk) -> (Bj, Bk, Bi); 这样我们就在数组A保持不变的同时把 (Bi, Bj, Bk)变成了(Bj, Bk, Bi);使得Bi从最前面变到了最后面, 这样带来的结果是如果B数组中没有重复元素的话, 这就让B数组的逆序对+2或者-2; 如果存在重复元素则是逆序对+1或者-1; 这样我们就可以跟据数组A和B中逆序对的数量来判断结果; 因为如果B中没有重复元素, 那么无论+2还是-2, 逆序对数量的奇偶性不会改变, 只要A和B的逆序对数量的奇偶性相同就可以转换; 如果有重复元素那么无论奇偶都可以转换; 当然上面的前提都是数组A和B在排序后是相同的;
代码中是用树状数组来求逆序对, 要把归并排序简洁很多;

神秘代码

#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;
typedef pair<int, int> PII;
int n, m;
int a[N], b[N], t1[N], t2[N], cb[N];
int lowbit(int x){
    return x&-x;
}
void add(int x, int t[]){
    for(int i = x; i <= n; i += lowbit(i)){
        t[i]++;
    }
}
int sum(int x, int t[]){
    int sum = 0;
    for(int i = x; i > 0; i -= lowbit(i)){
        sum += t[i];
    }
    return sum;
}
signed main(){
    cin >> n;
    bool fb = false;
    int x = 0, y = 0;
    for(int i = 1; i <= n; i++) {
        cin >> a[i];
        add(a[i], t1);
        x += sum(a[i] - 1, t1);
    }
    for(int i = 1; i <= n; i++) {
        cin >> b[i];
        if(cb[b[i]]) fb = true;
        cb[b[i]]++;
        add(b[i], t2);
        y += sum(b[i] - 1, t2);
    }
    sort(a + 1, a + 1 + n);
    sort(b + 1, b + 1 + n);
    for(int i = 1; i <= n; i++){
        if(a[i] != b[i]){
            cout << "No";
            return 0;
        }
    }
    if(fb){
        cout << "Yes";
        return 0;
    }
    if(x % 2 != y % 2){
        cout << "No";
    } 
    else cout << "Yes";
    return 0;
}

标签:AtCoder,abc,int,Bi,long,Ai,296,tie,define
From: https://www.cnblogs.com/mostimali/p/17840952.html

相关文章

  • AtCoder Beginner Contest 328
    B-11/11题意是:有n个月份,要你计算出月份上的每个数位与对应月份中的每个日期数位一致的日期和直接模拟即可usingnamespacestd;inta[200];intp;boolcheck(intx){ p=x%10; x/=10; while(x){ intq=x%10; if(q!=p)returnfalse; x/=10; } returntrue;}boo......
  • Atcoder 中高分段 选做 与 ARC vp
    开坑,主推红题和铜牌题,来源乱七八糟,目前一部分来自学校给的。一眼秒了标绿,想了很久或是接受了提示标蓝,看了题解或者认为题很难标红。意义重大标星。很主观(然后发现其实基本上大多数题都不会,狠狠地难过了)。以后有时间可能会开始板刷ARC,现在,还是,慢慢来吧。upd-2023-10-30:和Eray......
  • 【题解 ABC180F】 Unbranched
    [ABC180F]Unbranched题面翻译求\(N\)个点,\(M\)条边且满足以下条件的图的数量:图中无自环;每个点度数最多为\(2\);连通块大小的最大值恰好为\(L\)。答案对\(10^9+7\)取模。\(2\leN\le300\),\(1\leM,L\leN\)。题目描述頂点にラベルが付き辺にはラベルが付い......
  • [ABC288D] Range Add Query
    先考虑将原序列差分一下,事实上,我们对于这类每次可以操作一个区间减去固定值的时候,我们一般都需要差分,因为差分后,我们的操作实际上相当于**在差分序列上修改两个点**,这个时候的问题是好考虑的。这时候问题转化为,我们每次可以选择两个距离恰好为$k+1$的点,将$l$加上$w$,将$l......
  • AtCoder Beginner Contest(abc) 324
    B-3-smoothNumbers难度:⭐题目大意给定一个数字n,问是否可以找到两个数x和y,使得n=2x3y;解题思路因为n的范围最大到1e18,所以只需要暴力找x和y即可;神秘代码#include<bits/stdc++.h>#defineintlonglong#defineIOSios::sync_with_stdio(false),cin.......
  • abc280F - Pay or Receive(判断是否全为零环)
    https://atcoder.jp/contests/abc280/tasks/abc280_f对于每一个连通块单独处理,首先判断是否全为0环,可以用bfs判断。从一个点出发计算其他点到它的最短距离,如果存在一个不唯一,说明存在非零环。然后计算距离的时候直接-d[x]+d[y]即可#include<cstdio>#include<algorithm>#incl......
  • abc327F - Apples(线段树)
    https://atcoder.jp/contests/abc327/tasks/abc327_f我们将时间看作x轴,位置看作y轴,那么我们随着时间增加,维护新加的点对区间的贡献,同时减去过时的点,线段树区间加法维护最大值即可。#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#include<map>#incl......
  • AT_abc215_d
    基本概括当解决这个问题时,我们需要找到满足条件的整数\(k\),使得对于给定的序列\(A=(A_1,A_2,\dots,A_N)\)中的每个数\(A_i\),都满足\(\gcd(A_i,k)=1\)。实现思路首先,我们可以观察到,如果\(k\)是\(A_i\)的质因数或其倍数,那么\(\gcd(A_i,k)\)将不等于1。因此,我们可......
  • [题解]AT_abc267_f [ABC267F] Exactly K Steps
    大家好,我是毒瘤,喜欢用玄学算法过题。发现题解区没有这个做法,于是来发一篇。思路不难发现如果一个点对\((u,v)\)的距离为\(d\),那么在这棵树以\(u\)为根时,\(v\)的深度为\(d\)。于是考虑换根DP。首先思考如何计算答案。显然我们可以将查询离线下来,然后当换根到以\(u\)......
  • [ABC230F] Predilection
    题目描述:芷萱姐姐有一个长度为\(N\)的数列\(A_i\)。你可以进行若干次,最多\(N-1\)次操作,选择相邻的两个数,删去他们,并在原位置放上他们两个的和。现在你需要求出可能产生的序列个数。数据范围:\(1\leN\le2\times10^5\)\(|A_i|\le10^9\)思路:我们首先会发现一件......