AtCoder Beginner Contest 307 (A~E)

A - Weekly Records

思路:

每求7次累加,输出更新。

代码:

#include<bits/stdc++.h>

using namespace std;

const int N = 100010,mod = 1e6+7;
typedef long long ll;
typedef pair<int,int> pii;

int n,m,k;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n;
    ll sum = 0;
    for(int i = 1;i <= n * 7; i ++ )
    {
        ll x;
        cin >> x;
        sum += x;
        if(i % 7 == 0)
        {
            cout << sum << ' ';
            sum = 0;
        }
    }
    return 0;
}

B - racecar

思路:

暴力合并即可,检查是否是回文串。时间复杂度(n^2)。

代码:

#include<bits/stdc++.h>

using namespace std;

const int N = 100010,mod = 1e6+7;
typedef long long ll;
typedef pair<int,int> pii;

int n,m,k;
string s[110];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n;
    for(int i = 1;i <= n; i ++ ) cin >> s[i];
    for(int i = 1;i <= n; i ++ )
        for(int j = 1;j <= n; j ++ )
        {
            if(i == j) continue;
            string s1, s2;
            s1 = s[i] + s[j];
            s2 = s1;
            reverse(s2.begin(), s2.end());
            if(s1 == s2)
            {
                cout << "Yes\n";
                return 0;
            }
        }
    cout << "No\n";
    return 0;
}

C - Ideal Sheet

题目描述:就是两个图能否行成一个要求的图,格子有黑和透明的,操作就是将两个图分别覆盖在一个无穷大的二维平面上,只能平移的覆盖,不能剪切和翻转,能够相互覆盖,如果一个格子被黑的覆盖一定显示黑,有黑色的格子不得裁掉,两个图只能使用一次。

思路:

比赛的时候没怎么看懂题,以为这两个图a,b至少使用一次。两个图分别使用一次,就可以分别固定左上角的位置进行暴力枚举,O(10^4)。可以使用一个覆盖后的图与要求的图进行比较即可。一个注意的点,由于图放的位置可能导致黑格可能出界,那么我们可以开个35*35的图进行放置,a图能放的固定左上端点的位置(1~hc+10,1~hc+10),b图能放的固定左上端点的位置同a图一样。

代码:

#include<bits/stdc++.h>

using namespace std;

const int N = 100010,mod = 1e6+7;
typedef long long ll;
typedef pair<int,int> pii;

int ha,hb,hc,wa,wb,wc;
int a[15][15], b[15][15], c[35][35];
int ans[35][35];
char s[15];


int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    cin >> ha >> wa;
    for(int i = 1;i <= ha; i ++ )
    {
        cin >> (s + 1);
        for(int j = 1;j <= wa; j ++ )
            a[i][j] = (s[j] == '#');
    }
    cin >> hb >> wb;
    for(int i = 1;i <= hb; i ++ )
    {
        cin >> (s + 1);
        for(int j = 1;j <= wb; j ++ )
            b[i][j] = (s[j] == '#');
    }
    cin >> hc >> wc;
    for(int i = 1;i <= hc; i ++ )
    {
        cin >> (s + 1);
        for(int j = 1;j <= wc; j ++ )
            c[i + 10][j + 10] = (s[j] == '#'); //将目标图放在中间的位置,防止合成图出界
    }

    for(int i = 1;i <= hc + 10; i ++ )
        for(int j = 1;j <= wc + 10; j ++ )
            for(int k = 1;k <= hc + 10; k ++ )
                for(int l = 1;l <= wc + 10; l ++ )
                {
                    memset(ans, 0, sizeof ans);
                    //a图覆盖 (i,j)为a图最左上端点放的位置
                    for(int p = 1;p <= ha; p ++ )
                        for(int q = 1;q <= wa; q ++ )
                            if(a[p][q]) ans[i + p - 1][j + q - 1] = 1; 
                    //b图覆盖 (k,l)为b图最左上端点放的位置
                    for(int p = 1;p <= hb; p ++ )
                        for(int q = 1;q <= wb; q ++ )
                            if(b[p][q]) ans[k + p - 1][l + q - 1] = 1;
                    
                    int f = 1;
                    for(int p = 1;p <= 30; p ++ )
                        for(int q = 1;q <= 30; q ++ )
                            if(ans[p][q] != c[p][q]) f = 0;
                    if(f)
                    {
                        cout << "Yes\n";
                        return 0;
                    }
                }
    cout << "No\n";
    return 0;
}

D - Mismatched Parentheses

思路:

一个括号匹配问题,用栈去维护,如果栈中有(,并且当时访问到的是)那么,就将最近的(及右边的所有东西出栈。

代码:

#include<bits/stdc++.h>

using namespace std;

const int N = 100010,mod = 1e6+7;
typedef long long ll;
typedef pair<int,int> pii;

int n,m,k;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n;
    string s;
    cin >> s;
    stack<char> st;
    int cnt = 0;
    for(int i = 0;i < s.size(); i ++ )
    {
        char ch = s[i];
        if(ch == ')' && cnt) 
        {
            while(st.top() != '(') st.pop();
            st.pop();
            cnt--;
        }
        else 
        {
            st.push(ch);
            if(ch == '(') cnt++;
        }
    }
    string ans;
    while(!st.empty()) 
    {
        ans += st.top();
        st.pop();
    }
    reverse(ans.begin(), ans.end());
    cout << ans << '\n';
    return 0;
}

E - Distinct Adjacent

思路:

当时看完题目感觉有点像当初圆环类涂色问题,n为人的个数,m为人可以拿的数。

(-1)^n*(m-1)+(m-1)^n,证明的话,我不太确定这样有没有问题,还是写一些。

首先第一个人可以用m种数,接下来的人都拿m-1种数,方法数m*(m-1)^{n-1},第一个人和第n个人可能拿到相同的,需要去重,将1和n颜色相同时合并看作一个人,此时变成n-1个人m种颜色且两两相近的颜色不同的方案数,写出数列关系式a_n=m*(m-1)^{n-1} - a_{n-1}

进行递推

a_n=-a_{n-1}+m*(m-1)^{n-1}\\ =-(-a_{n-2}+m*(m-1)^{n-2})+m*(m-1)^{n-1}\\ =-a_{n-3}+m*(m-1)^{n-3}-m*(m-1)^{n-2}+m*(m-1)^{n-1} \\=...\\ = m*[(m-1)^{n-1}-(m-1)^{n-2}+...+(-1)^n*(m-1)]\\=(m-1+1)*[(m-1)^{n-1}-(m-1)^{n-2}+...+(-1)^n*(m-1)]\\ =[(m-1)^n-(m-1)^{n-1}+(m-1)^{n-2}+...+(-1)^n*(m-1)^2]\\ +[(m-1)^{n-1}-(m-1)^{n-2}+...+(-1)^n*(m-1)]\\ =(-1)^n*(m-1)+(m-1)^n

不怎么会用latex,请见谅。

代码:

#include<bits/stdc++.h>

using namespace std;

const int N = 100010,mod = 998244353;
typedef long long ll;
typedef pair<int,int> pii;

int n,m,k;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> m;
    ll ans = 0;
    if(n & 1) ans = -(m - 1);
    else ans = m - 1;
    ll t = m - 1;
    for(int i = 1;i < n; i ++ )
    {
        t = (t * (m - 1)) % mod;
    }
    ans = (ans + t + mod) % mod;
    cout << ans << '\n'; 
    return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值