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

AtCoder Beginner Contest(abc) 304

时间:2023-06-20 13:11:06浏览次数:39  
标签:AtCoder abc idx int 304 cin long 蛋糕 find




A - First Player

题目大意

顺时针给定一个序列, 序列的元素由一个字符串和一个数字组成; 我们需要从有最小数字的元素开始, 顺时针遍历整个序列, 并输出字符串;

解题思路

签到题不多嗦了;

神秘代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<string,int> PSI;
const int N=110;
int n;
vector<PSI> v;
signed main() {
    cin >> n;
    int pos = 0,minn = 1e9+10;
    for (int i = 1; i <= n; i++) {
        string a;
        int b;
        cin >> a >> b;
        v.push_back({ a,b });
        if (b < minn) {
            minn = b;
            pos = i-1;
        }
    }
    for (int i = 1, j = pos; i <= n; j++, i++) {
        if (j == n) j = 0;
        cout << v[j].first << endl;
    }
    return 0;
}




B - Subscribers

题目大意

给定一个数, 只保留前三位数, 其他位数变为0; 若不足三位则直接输出原数;

解题思路

签到题不多嗦了;

神秘代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> PII;
const int N=110;
int n;
signed main() {
    string s;
    cin >> s;
    int len = s.size();
    if (len < 4) cout << s;
    else {
        for (int i = 0; i < len; i++) {
            if (i >= 3) cout << 0;
            else cout << s[i];
        }
    }
    return 0;
}




C - Virus

题目大意

给定一个只有'#'和'.'组成的矩阵, 问由'#'组成的X形状的各种大小的都有多少个

解题思路

数量不大, 直接暴力

神秘代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N = 110;
char g[N][N];
int dx[] = { 1,1,-1,-1 }, dy[] = { 1,-1,1,-1 };
int n,m;
map<int, int> mp;
void check(int x, int y) {
    bool f = true;
    int idx = 0;
    while (1) {
        for (int i = 0; i < 4; i++) {
            int a = x + dx[i]*(idx+1), b = y + dy[i]*(idx+1);
            if (a<1 || a>n || b<1 || b>m||g[a][b] != '#') {
                f = false;
                break;
            }
        }
        if (!f) break;
        idx++;
    }
    mp[idx]++;
}
signed main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> g[i][j];
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (g[i][j] == '#') {
                check(i, j);
            }
        }
    }
    int num = min(n, m);
    for (int i = 1; i <= num; i++) {
        cout << mp[i] << ' ';
    }
    return 0;
}




D - A Piece of Cake

题目大意

给定一个长宽为n和m的矩形蛋糕, 蛋糕上有k个草莓; 然后我们要对着蛋糕竖着切a刀, 横着切b刀; 每一刀都给出其对应在x轴或y轴上的坐标; 注意切的时候不会切到有草莓的那一行或列; 并且也不会切边缘的行和列, 而草莓也不会在边缘的行和列上; 切完之后, 找到所有蛋糕块里面含有草莓数量最少和最多的数量, 并输出这两个数;

解题思路

这个题的长和宽数据比较大, 而且a和b也都是1e5级别的; 所以我们不能从矩阵或者每块蛋糕的角度出发; 而草莓数量也是1e5; 所有我们可以从每个草莓下手; 我们可以遍历所有草莓, 然后找到其所在的蛋糕块, 然后更新该蛋糕块上草莓的数量, 这个我们可以用map来完成; 对于怎么找对应的蛋糕块, 我们可以用二分查找小于草莓坐标的坐标最大的横竖两刀, 而这两刀的交点就是该蛋糕块的左上角, 我们可以用它来代表该蛋糕块; 如果map里的蛋糕块数量小于所有的蛋糕块数量((a+1) * (b+1)), 那说明有蛋糕块上没有草莓, 故最小值为0;

神秘代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> PII;
const int N=110;
int n,m,k;
map<PII, int> mp;
vector<PII> v;
set<int> s1;
set<int> s2;
signed main() {
    cin >> m >> n >> k;
    while (k--) {
        int a, b;
        cin >> a >> b;
        v.push_back({ b,a });
    }
    sort(v.begin(), v.end());
    int a, b;
    cin >> a;
    for (int i = 1; i <= a; i++) {
        int x;
        cin >> x;
        s1.insert(x);
    }
    cin >> b;
    for (int i = 1; i <= b; i++) {
        int x;
        cin >> x;
        s2.insert(x);
    }
    for (int i = 0; i < v.size(); i++) {
        int x = v[i].first;
        int y = v[i].second;
        int x1, y1;
        auto p1 = s2.lower_bound(x);
        if (p1 == s2.end()) x1 = 0;
        else x1 = *p1;
        auto p2 = s1.lower_bound(y);
        if (p2 == s1.end()) y1 = 0;           
        else y1 = *p2;
        mp[{x1, y1}]++;
    }
    int num = (a + 1) * (b + 1);
    int res = 0;
    int minn = 1e9 + 10;
    int maxn = 0;
    for (auto t : mp) {
        int idx = t.second;
        minn = min(minn, idx);
        maxn = max(maxn, idx);
        res += idx;
    }
    if (mp.size() <num) cout << 0 << ' ';
    else cout << minn << ' ';
    cout << maxn;
    return 0;
}




E - Good Graph

题目大意

给定一个无向图, 有n个点和m条边并给出这m条边, 再给出k组{ xi, yi } ( i = 1, 2, 3...k), 如果所有的xi和yi之间都没有边相连, 那么这个无向图就是合法的; 现在再给出q组{ xj, yj } ( j = 1, 2, 3...q), 每一组就是一次询问, 问如果把当前的xj和yj相连, 那此时无向图是否合法;
注意可能存在重边或自环; 而且相连不一定是直接相连, 1-2-5这种情况也算1和5相连

解题思路

很明显的一个并查集问题, 初识情况就是给了许多个连通块; 然后给出k组限制, 一开始我还在想, k和q都是1e5级别的, 肯定不能去一个个查; 后来小莫提醒到了我, 不要去关注每个点, 只需要看每个连通块就行; 于是我们可以把k的限制看成是规定了某些连通块之间不能相连, 而不是点之间不能相连; 我们可以用set把不能相连的连通块存起来, 方便后期查找; 对于q组询问, 我们只需要看看给出的两个点所在的连通块是否在set里面存着, 如果没有则就是合法的;

神秘代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> PII;
const int N=1e6+10;
int n,m,c,d;
int p[N];
set<PII> s;
int find(int x) {
    if (p[x] != x) p[x] = find(p[x]);
    return p[x];
}
signed main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++)  p[i] = i;
    for (int i = 1; i <= m; i++) {
        int a, b;
        cin >> a >> b;
        if (find(a) != find(b))  p[find(b)] = find(a);
    }
    cin >> c;
    for (int i = 1; i <= c; i++) {
        int a, b;
        cin >> a >> b;
        s.insert({ find(a),find(b)});
    }
    cin >> d;
    for (int i = 1; i <= d; i++) {
        int a, b;
        cin >> a >> b;
        if ((s.count({ find(a),find(b) })) || (s.count({ find(b),find(a) }))) {
            cout << "No" << endl;
        }
        else cout << "Yes" << endl;
    }
    return 0;
}




F - Shift Table

题目大意

待定.....

解题思路

待定....

神秘代码

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=1e6+10;
int w[N],d[N];
int n,m,idx;
bool st[N];
vector<int> v[N];
int dijkstra(){
    memset(d,0x3f,sizeof d);
    priority_queue<PII,vector<PII>,greater<PII>> heap;
    heap.push({0,1});
    d[1]=0;
    while(heap.size()){
        auto t=heap.top();
        heap.pop();
        int x=t.second;
        if(st[x]) continue;
        st[x]=true;
        for(int p:v[x]){
            if(d[p]>d[x]+w[p]){
                d[p]=d[x]+w[p];
                heap.push({d[p],p});
            }
        }
    }
    if(d[m]==0x3f3f3f3f) return -1;
    else return d[m]-1;
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        int k;
        cin>>k;
        w[i+m] =1;
        for(int j=1;j<=k;j++){
            int x;
            cin>>x;
            v[x].push_back(i+m);
            v[i+m].push_back(x);
        }
    }
    cout<<dijkstra();
    return 0;
}

标签:AtCoder,abc,idx,int,304,cin,long,蛋糕,find
From: https://www.cnblogs.com/mostimali/p/17492495.html

相关文章

  • 20230410 java.util.HashMap
    问题第一部分,基础入门:1.数组的优势/劣势2.链表的优势/劣势3.有没有一种方式整合两种数据结构的优势?散列表4.散列表有什么特点?5.什么是哈希?第二部分,HashMap原理讲解:1.HashMap的继承体系是什么样的?2.Node数据结构分析?3.底层存储结构介绍?4.put数据原理分析?5.什么是Hash碰......
  • 20230411 java.lang.Iterable
    介绍publicinterfaceIterable<T>实现此接口允许对象成为“for-each循环”语句的目标//遍历集合for(Suitsuit:suits)//遍历数组for(inti:a)只有一个抽象方法iterator,是函数式接口方法iterator返回迭代器forEach对Iterable的每个元素执行给......
  • 20230411 java.util.BitSet
    简介publicclassBitSetimplementsCloneable,java.io.Serializable没有实现Set接口此类实现了一个按需增长的位向量每个位对应一个布尔值BitSet的位由非负整数索引可以检查、设置或清除各个索引位。一个BitSet可以通过逻辑与、逻辑或、逻辑异或运算修改另一个Bit......
  • 20230407 11.1. 散列表
    引入概念已知的几种查找方法:查找方法时间复杂度顺序查找O(N)二分查找(静态查找)\(O(log_2N)\)二叉搜索树O(h)h为二叉查找树的高度平衡二叉树\(O(log_2N)\)【问题】如何快速搜索到需要的关键词?如果关键词不方便比较怎么办?查找的本质:已知对象找位置......
  • 20230410 11.2. 散列函数的构造方法
    一个“好”的散列函数一般应考虑下列两个因素:计算简单,以便提高转换速度;关键词对应的地址空间分布均匀,以尽量减少冲突。数字关键词的散列函数构造直接定址法取关键词的某个线性函数值为散列地址,即\(h(key)=a*key+b(a、b为常数)\)除留余数法散列函数为:\(h(key)......
  • 20230410 11.3. 冲突处理方法
    处理冲突的方法开放地址法:换个位置链地址法:同一位置的冲突对象组织在一起散列表查找性能分析成功平均查找长度(ASLs)不成功平均查找长度(ASLu)开放定址法(OpenAddressing)一旦产生了冲突(该地址已有其它元素),就按某种规则去寻找另一空地址若发生了第i次冲突,试探的下一......
  • 20230410 11.4. 散列表的性能分析
    平均查找长度(ASL)用来度量散列表查找效率:成功、不成功关键词的比较次数,取决于产生冲突的多少影响产生冲突多少有以下三个因素:散列函数是否均匀;处理冲突的方法;散列表的装填因子α开放地址法:散列表是一个数组,存储效率高,随机查找。散列表有“聚集”现象分离链法:散列......
  • abc045d
    https://atcoder.jp/contests/abc045/tasks/arc061_b//https://atcoder.jp/contests/abc045/tasks/arc061_b//注意到每个格子染色仅能影响到周围范围的格子,因而对N个染色点进行枚举//为了不重复,仅枚举每个染色点影响到的右下侧共3*3个格子//统计每个格子被覆盖的次数,......
  • abc044d <根号分治>
    https://atcoder.jp/contests/abc044/tasks/arc060_b//https://atcoder.jp/contests/abc044/tasks/arc060_b//根号分治//将数据范围分为两部分处理,使得拆开成两部分后各部分复杂度均符合要求#include<iostream>#include<algorithm>#include<cmath>usingnamespace......
  • [ABC216G] 01Sequence 题解
    01Sequence题目大意构造一个满足\(m\)个形如\((l,r,x)\)的限制条件的\(01\)序列,其中\((l,r,x)\)表示区间\([l,r]\)的和不小于\(x\),你需要保证序列中\(1\)的个数最小。思路分析贪心的想,如果我们将限制按右端点排序,那么当遍历到一个区间,发现现有的和不满足限制条件......