【atcoder】ABC练习记录DAY2

ABC308

B - Default Price

题意

给出不同字符串对应的权值,再给出一系列字符串,问这些字符串的总价值,如果有没有告知权值的字符串就默认价格为一个固定给定值

思路

用map存数据,直接查找

代码

#include <bits/stdc++.h>

using namespace std;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    int n, m;
    cin >> n >> m;
    vector<string> c(n);
    vector<string> d(m);
    vector<int> p(m);
    map<string, int> dp;
    for (int i = 0; i < n; i ++ ) cin >> c[i];
    for (int i = 0; i < m; i ++ ) cin >> d[i];
    int p0;
    cin >> p0;
    for (int i = 0; i < m; i ++ ) cin >> p[i];
    
    for (int i = 0; i < m; i ++ )
    {
        dp[d[i]] = p[i];
    }
    int ans = 0;
    for (int i = 0; i < n; i ++ )
    {
        if (dp.find(c[i]) == dp.end()) ans += p0;
        else
        {
            ans += dp[c[i]];
        }
    }
    cout << ans;
}

C - Standings

题意

每组给出两个数 a b,按照 a / (a + b) 从大到小的顺序输出排序,如果值一样就按照输入顺序输出

思路

如果用分式会过不掉后四个测试点(还不知道为什么)
把分式稍微化简一下改成乘式比较即可

代码

#include <bits/stdc++.h>

using namespace std;

typedef pair<pair<long double, int>, int> PII;

bool cmp(PII a, PII b)
{
    if (a.first.first * b.first.second != b.first.first * a.first.second)
        return a.first.first * b.first.second > b.first.first * a.first.second;
    else return a.second < b.second;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    int n;
    cin >> n;
    vector<int> a(n);
    vector<int> b(n);
    vector<PII> c(n);
    for (int i = 0; i < n; i ++ )
    {
        cin >> a[i] >> b[i];
        pair<int, int> d;
        d = make_pair(a[i], b[i]);
        c[i] = make_pair(d, i + 1);
    }
    sort(c.begin(), c.end(), cmp);
    for (int i = 0; i < n; i ++ ) cout << c[i].second << ' ';
}

ABC307

B - racecar

题意

给出一系列字符串,问有没有两个拼接起来能形成回文字符串

思路

暴力拼接,每接一个判断一次

代码

#include <bits/stdc++.h>

using namespace std;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    int n;
    cin >> n;
    vector<string> ss(n);
    for (int i = 0; i < n; i ++ ) cin >> ss[i];
    for (int i = 0; i < n; i ++ )
    	for (int j = 0; j < n; j ++ )
        	if (i != j)
            {
                string s = ss[i] + ss[j];
                string s1 = s;
                reverse(s1.begin(), s1.end());
                if (s == s1)
                {
                    cout << "Yes";
                    return 0;
                }
            }
    cout << "No";
}

C - Ideal Sheet

题意

每个图由黑色块和透明色块组成,现在给出三个图,问前两个图能不能通过叠在一起的方式得到第三个图

思路

枚举前两个图叠在一起的所有情况,看和第三个图是不是一样的(好复杂啊TAT…

代码

#include <bits/stdc++.h>

using namespace std;

const int N = 21;

int Ha, Wa, Hb, Wb, Hx, Wx;
string a[N], b[N], x[N];
int cnt_a, cnt_b, cnt_x;

bool check(int i, int j, int k, int l)
{
    int sum = 0;
    for (int r = 0; r < Hx; r ++ )
        for (int p = 0; p < Wx; p ++ )
        {
            int flag = 0;
            int check_a = 0, check_b = 0;
            if (x[r][p] == '#') flag = 1;
            if (r >= i && p >= j && r - i < Ha && p - j < Wa && a[r - i][p - j] == '#') check_a = 1;
            if (r >= k && p >= l && r - k < Hb && p - l < Wb && b[r - k][p - l] == '#') check_b = 1;
            sum += check_a + check_b;
            if (flag != (check_a || check_b)) return false;
        }
    if (sum == cnt_a + cnt_b) return true;
    else return false;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    cin >> Ha >> Wa;
    for (int i = 0; i < Ha; i ++ )
    {
        cin >> a[i];
        cnt_a += count(a[i].begin(), a[i].end(), '#');
    }
    cin >> Hb >> Wb;
    for (int i = 0; i < Hb; i ++ )
    {
        cin >> b[i];
        cnt_b += count(b[i].begin(), b[i].end(), '#');
    }
    cin >> Hx >> Wx;
    for (int i = 0; i < Hx; i ++ )
    {
        cin >> x[i];
        cnt_x += count(x[i].begin(), x[i].end(), '#');
    }

    for (int i = -10; i <= 10; i ++ )
        for (int j = -10; j <= 10; j ++ )
            for (int k = -10; k <= 10; k ++ )
                for (int l = -10; l <= 10; l ++ )
                {
                    if (check(i, j, k, l))
                    {
                        cout << "Yes";
                        return 0;
                    }
                    
                }

    cout << "No";
    return 0;
}

ABC306

B - Base 2

题意

给出64个系数,求二的 0 - 63 次方之和

思路

只说一句…会卡 long long…

代码

#include <bits/stdc++.h>

using namespace std;

using i64 = unsigned long long;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    int t = 64;
    int k[t];
    for (int i = 0; i < t; i ++ ) cin >> k[i];
    i64 sum = 0;
    i64 a = 1;
    for (int i = 0; i < t; i ++ )
    {
        sum += k[i] * a;
        a *= 2;
    }
    cout << sum;
}

C - Centers

题意

给出一个 n ,有一个长度为 3n 的数组里 1 - n 重复出现了 3 次(顺序随机)
输出每个数字第二次出现的排序

思路

记录下每个数字第二次出现的位置,用 pair 存下来,按位置排序后输出该数字

代码

#include <bits/stdc++.h>

using namespace std;

const int N = 100010;

typedef pair<int, int> PII;

int main()
{
	ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    
    int n;
    cin >> n;
    int status[N];
    memset(status, 0, sizeof status);
    vector<PII> comp(n + 1);
    for (int i = 0; i < 3 * n; i ++ )
    {
        int x;
        cin >> x;
        if (status[x] == 1)
        {
            comp[x] = make_pair(i, x);
        }
        status[x] ++ ;
    }

    sort(comp.begin(), comp.end());
    for (int i = 1; i <= n; i ++ )
    {
        cout << comp[i].second << ' ';
    }
}

ABC305

B - ABCDEFG

题意

给出每两个字母间的距离,求给定两个字母的距离

思路

看作是小的那个字母一步步往大的字母挪,每挪一步加上那一步的长度

代码

#include <bits/stdc++.h>

using namespace std;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    
    char p, q;
    cin >> p >> q;
    int dist[6] = {3, 1, 4, 1, 5, 9};
    if (p > q) swap(p, q);

    int sum = 0;
    while (p != q)
    {
        sum += dist[p - 'A'];
        p ++ ;
    }
    cout << sum;
}

C - Snuke the Cookie Picker

题意

在一个大矩形里存在一个小矩形,使得大矩形的其他部分全是’.‘,只有小矩形里是’#'。现在小矩形缺了一块,问缺的是哪一块

思路

判断所有的’.‘看它的上下左右是否有两个以上的’#’

代码

#include <bits/stdc++.h>

using namespace std;

const int N = 510;

char g[N][N];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    
    int h, w;
    cin >> h >> w;
    for (int i = 1; i <= h; i ++ )
        for (int j = 1; j <= w; j ++ )
            cin >> g[i][j];

    for (int i = 1; i <= h; i ++ )
        for (int j = 1; j <= w; j ++ )
        {
            int res = 0;
            if (g[i][j] == '.')
            {
                if (g[i - 1][j] == '#') res ++ ;
                if (g[i + 1][j] == '#') res ++ ;
                if (g[i][j - 1] == '#') res ++ ;
                if (g[i][j + 1] == '#') res ++ ;
            }
            if (res >= 2)
            {
                cout << i << ' ' << j;
                return 0;
            }
        }
}

ABC304

B - Subscribers

题意

按题目要求输出数字

思路

把数字理解成字符串,前三位正常输出,后面的全部换成0

代码

#include <bits/stdc++.h>

using namespace std;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    
    string s;
    cin >> s;
    int len = s.size();
    if (len <= 3) cout << s;
    else
    {
        for (int i = 0; i < len; i ++ )
        {
            if (i <= 2) cout << s[i];
            else cout << 0;
        }
    }
}

C - Virus

题意

有 n 个人,1 有病,距离 d 之内都会被传染,问每个人到最后是否会被传染

思路

存图,如果两个个人之间距离小于等于 d ,就说明这两个人之间有边,最后遍历,能从第 1 个人走到的人都会被传染

代码

#include <bits/stdc++.h>

using namespace std;

const int N = 2010;

typedef pair<int, int> PII;

vector<int> g[N];
bool flag[N];
bool visted[N];

void dfs(int u)
{
    flag[u] = true;
    for (int j = 0; j < g[u].size(); j ++ )
    {
        int t = g[u][j];
        if (!flag[t])
        {
            flag[t] = true;
            dfs(t);
        }
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    int n, d;
    cin >> n >> d;
    d *= d;
    vector<int> x(n);
    vector<int> y(n);
    cin >> x[0] >> y[0];
    
    for (int i = 1; i < n; i ++ )
    {
        cin >> x[i] >> y[i];
        for (int j = 0; j < i; j ++ )
        {
            int dist = (x[j] - x[i]) * (x[j] - x[i]) + (y[j] - y[i]) * (y[j] - y[i]);
            if (dist <= d)
            {
                g[i].push_back(j);
                g[j].push_back(i);
            }
        }
    }

    dfs(0);
    for (int i = 0; i < n; i ++ )
    {
        if (flag[i]) cout << "Yes\n";
        else cout << "No\n";
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Texcavator

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值