Atcoder Beginner Contest 045

B.B - Card Game for Three (ABC Edit)

用三个队列(分别将三个字符串的各个字符入队,当然也可以用栈,不过得反着入栈)

然后按照题目的操作先将第一个队列的第一个字符取出,该字符如果是'b',就取出第二个队列的第一个字符,如果取出的这个字符是'C',而第三个队列此时为空,那么C赢了

我调试了半天,后才发现题目理解错了,以为C为空是它的上一级B赢了,所以得花多点时间用心读题,题目理解错就会浪费大量时间

错误代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
char t, ch;
int main()
{
    queue<char>a;
    queue<char>b;
    queue<char>c;
    char s[1000];
    cin >> s;
    for (int i = 0; i < strlen(s); i++) {
        a.push(s[i]);
    }
    cin >> s;
    for (int i = 0; i < strlen(s); i++) {
        b.push(s[i]);
    }
    cin >> s;
    for (int i = 0; i < strlen(s); i++) {
        c.push(s[i]);
    }
    t = a.front();
    a.pop();
    ch = 'A';
    /*printf("t=%c ch=%c\n", t, ch);*/
    while (1) {
        if (t == 'a') {
            if (a.empty()) {
                cout << ch << endl;
                return 0;
            }
            if (a.size()) {
                t = a.front();
                a.pop();
                ch = 'A';
                /*printf("t=%c ch=%c\n", t, ch);*/
            }
        }
        else if (t == 'b') {
            if (b.empty()) {
                cout << ch << endl;
                return 0;
            }
            if (b.size()) {
                t = b.front();
                b.pop();
                ch = 'B';
                /*printf("t=%c ch=%c\n", t, ch);*/
            }
        }
        else if (t == 'c') {
            if (c.empty()){
                cout << ch << endl;
                return 0;
            }
            if (c.size()) {
                t = c.front();
                c.pop();
                ch = 'C';
                /*printf("t=%c ch=%c\n", t, ch);*/
            }
        }
    }
    return 0;
}

 AC代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
char t;
int main()
{
    queue<char>a;
    queue<char>b;
    queue<char>c;
    char s[1000];
    cin >> s;
    for (int i = 0; i < strlen(s); i++) {
        a.push(s[i]);
    }
    cin >> s;
    for (int i = 0; i < strlen(s); i++) {
        b.push(s[i]);
    }
    cin >> s;
    for (int i = 0; i < strlen(s); i++) {
        c.push(s[i]);
    }
    t = a.front();
    a.pop();
    while (1) {
        if (t == 'a') {
            if (a.empty()) {
                cout << 'A' << endl;
                return 0;
            }
            if (a.size()) {
                t = a.front();
                a.pop();
            }
        }
        else if (t == 'b') {
            if (b.empty()) {
                cout << 'B' << endl;
                return 0;
            }
            if (b.size()) {
                t = b.front();
                b.pop();
            }
        }
        else if (t == 'c') {
            if (c.empty()){
                cout << 'C' << endl;
                return 0;
            }
            if (c.size()) {
                t = c.front();
                c.pop();
            }
        }
    }
    return 0;
}

C.C - Many Formulas 

这题题目也是理解错了,我将字符串分成两部分,然后转化成十进制后相加,真的是完全理解错了

感觉近期题目读的不是很仔细,理解有各种错误,痛定思痛,以后必须花时间读题

错误代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
typedef long long LL;
LL ans;
LL sum(char s[],int x,int y) {
    LL sum1 = 0;
    int k;
    for (k = x; k <=y; k++) {
        sum1 = sum1 * 10 +(s[k]-'0');
    }
    return sum1;
}
int main()
{
    char s[20];
    cin >> s;
    //LL sum1 = sum(s,0,strlen(s)-1);

    //for (int i = 0; i < strlen(s); i++) {
    //    sum1 = sum1 * 10 + (s[i] - '0');
    //}
    //cout << sum1 << endl;
    int n = strlen(s);
    for (int i = 0; i <n; i++) {
        ans += (sum(s, 0, i) + sum(s, i+1, n - 1));
    }
    cout << ans << endl;
    return 0;
}

该题就是是否在数字与数字之间加上加号,可以用dfs来确定各种情况,但是不知道如何用代码实现,可以等价地用另一种表达

该题就是连续地选取子段数字加起来,可以用dfs来确定选取哪几段

  

首先将每一位预先存起来,方便后面乘10取数,但是存起来是反的,所以要倒过来,用reverse函数反转数组,然后就开始dfs搜索

以要加的数字为1层,以125为例,第一层数字可以为1,12,125

如果第一层数字为1,那么第二层数字就从2开始,2,25

如果第二层数字为2,那么第三层数字就从5开始,5

如果第二层数字为25,那么第三层数字就从5后面的数字开始,但是已经没有了,就结束了

i=x to n横向同一层铺排,dfs纵向一层一层深搜 

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define int long long 
const int N = 110;
int n;
int ans;
int num[N];
void dfs(int x, int sum) {
    if (x == n + 1) {
        ans += sum;
        return;
    }
    int tmp = 0;
    for (int i = x; i <= n; i++) {
        tmp = tmp * 10 + num[i];
        dfs(i + 1, sum + tmp);
    }
}
signed main()
{
    int x;
    cin >> x;
    while (x) {
        num[++n] = x % 10;
        x /= 10;
    }
    reverse(num + 1, num + 1 + n);
    dfs(1, 0);
    cout << ans << endl;
}

 D.D - Snuke's Coloring

包含的题目可以从贡献度的角度去考虑 

 

对于每一个涂黑的格子,可以枚举它周围的八个格子(当然,出界的格子就不算),对它周围的格子贡献度+1

如果以某个格子为中心的九宫格是完整的,那么这个中心的格子代表一个矩阵

比如说a对b的贡献度+1,说明了a在b的四周,同时说明b在a的四周,即a在以b为中心的九宫格里,那么也就是说有几个格子对b有贡献度,就说明以b为中心的矩阵包含了几个涂色的格子

 

再看c对b的贡献度+1,说明c在以b为中心的矩阵里 

 

 在加上b本身对以b为中心的矩阵贡献度+1,所以以b为中心的矩阵包含了三个涂色的格子

 

 那么只要预先处理好每个格子被贡献了多少度,然后枚举每个矩阵(通过枚举格子(以该格子为中心,可以形成完整的九宫格),也就是除去边界的格子),得到每个矩阵包含了几个涂色的格子,然后用桶计数,得到包含1个涂色格子的矩阵有几个,包含2个涂色格子的矩阵有几个...最后输出就行了

用map函数映射

c++中的map会自动根据first值排序,这样排好序后输出第一个用begin,输出最后一个用begin

用结构体的话不要忘了设置排序的顺序

map::iterator it;

for ( it = mp.begin(); it != mp.end(); it++)

it->first表示Node的值

it->second表示int的值

#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
using namespace std;
#define int long long
const int N = 100010;
struct Node {
    int x, y;
    bool operator<(const Node& W)const {
        if (x != W.x) return x < W.x;
        return y < W.y;
    }
}q[N];
map<Node, int>mp;
int dx[8] = { 0,0,-1,1,-1,-1,1,1 }, dy[8] = { -1,1,0,0,-1,1,-1,1 };
int bucket[10];
signed main()
{
    int h, w, n;
    cin >> h >> w >> n;
    for (int i = 1; i <= n; i++) {
        int x, y;
        cin >> x >> y;
        q[i] = { x,y };
        mp[q[i]]=1;
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < 8; j++) {
            int x = q[i].x + dx[j], y = q[i].y + dy[j];
            if (x >= 1 && x <= h && y >= 1 && y <= w) {
                Node temp;
                temp.x = x, temp.y = y;
                mp[temp]++;
            }
        }
    }
    int sum = (h - 2) * (w - 2);//总共的矩阵数
    int cnt = 0;
    //map<Node, int>::iterator it;
    for (auto it = mp.begin(); it != mp.end(); it++) {
        int x = it->first.x;
        int y = it->first.y;
        int val = it->second;
        if (x >= 2 && x <= h - 1 && y >= 2 && y <= w - 1) {
            bucket[val]++;//桶计数,记录包含val个涂色格的矩阵有几个
            cnt++;//记录除了包含0个涂色格的矩阵的总个数
        }
    }
    bucket[0] = sum - cnt;//用总的矩阵数减去除了包含0个涂色格的矩阵数,
    //来算包含0个涂色格的矩阵数,因为map函数对于那些被贡献度为0的格子是没有记录的,
    //所以最后bucket[0]并没有计算,故要单独计算

    for (int i = 0; i < 10; i++) {
        cout << bucket[i] << endl;
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值