AtCoder Beginner Contest 178 总结

A - Not

签到题

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
int main()
{
    IO;
    int T=1;
    //cin>>T;
    while(T--)
    {
        int x;
        cin>>x;
        cout<<1-x<<endl;
    }
    return 0;
}

B - Product Max

签到题

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=100010;
int main()
{
    IO;
    int T=1;
    //cin>>T;
    while(T--)
    {
        ll a,b,c,d;
        cin>>a>>b>>c>>d;
        cout<<max(max(a*c,a*d),max(b*c,b*d))<<endl;
    }
    return 0;
}

C - Ubiquity

正难则反,容斥原理
先只考虑满足第一个情况的方案数: 1 0 n 10^n 10n
那么其中肯定有不满足第二个情况和第三个情况的方案,我们只要减去这种情况即可。
满足第一个条件,不满足第二个条件的方案数是 9 n 9^n 9n
满足第一个条件,不满足第三个条件的方案数是 9 n 9^n 9n
满足第一个条件,同时不满足第二个条件和第三个条件的方案数是 8 n 8^n 8n
根据容斥原理,满足第一个条件但是不满足第二个条件或者第三个条件的方案数是 9 n + 9 n − 8 n 9^n+9^n-8^n 9n+9n8n
因此答案是 1 0 n − ( 9 n + 9 n − 8 n ) 10^n-(9^n+9^n-8^n) 10n(9n+9n8n)

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=100010;
const ll mod=1e9+7;
ll qmi(ll a,ll b)
{
    ll res=1;
    while(b)
    {
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
int main()
{
    IO;
    int T=1;
    //cin>>T;
    while(T--)
    {
        ll n;
        cin>>n;
        cout<<((qmi(10ll,n)-2*qmi(9ll,n)+qmi(8ll,n))%mod+mod)%mod<<'\n';
    }
    return 0;
}

D - Redistribution

考试的时候老想着完全背包。。
f [ i ] f[i] f[i]表示用 3 … i 3 \dots i 3i这些数凑成和是 i i i的方案数
转移:考虑最后一个数用的是谁?
f [ i ] = f [ i − 3 ] + f [ i − 4 ] + ⋯ + f [ i − i ] f[i]=f[i-3]+f[i-4]+\dots+f[i-i] f[i]=f[i3]+f[i4]++f[ii]

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=2010;
const ll mod=1e9+7;
ll f[N];
int main()
{
    IO;
    int T=1;
    //cin>>T;
    while(T--)
    {
        int s;
        cin>>s;
        f[0]=1;
        for(int i=3;i<=s;i++)
            for(int j=3;j<=i;j++)
                f[i]=(f[i]+f[i-j])%mod;
        cout<<f[s]<<'\n';
    }
    return 0;
}

E - Dist Max

考虑两个点 ( x 1 , y 1 ) (x_1,y_1) (x1,y1) ( x 2 , y 2 ) (x_2,y_2) (x2,y2)的曼哈顿距离 ∣ x 1 − x 2 ∣ + ∣ y 1 − y 2 ∣ |x_1-x_2|+|y_1-y_2| x1x2+y1y2其实还可以进一步简化成 m a x ( ∣ ( x 1 + y 1 ) − ( x 2 + y 2 ) ∣ , ∣ ( x 1 − y 1 ) − ( x 2 − y 2 ) ∣ ) max(|(x_1+y_1)-(x_2+y_2)|,|(x_1-y_1)-(x_2-y_2)|) max((x1+y1)(x2+y2),(x1y1)(x2y2))
由此将问题降维,然后就很容易解了。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=200010;
int d1[N],d2[N],n;
int main()
{
    IO;
    int T=1;
    //cin>>T;
    while(T--)
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            int x,y;
            cin>>x>>y;
            d1[i]=x+y;
            d2[i]=x-y;
        }
        sort(d1+1,d1+1+n);
        sort(d2+1,d2+1+n);
        cout<<max(d1[n]-d1[1],d2[n]-d2[1])<<'\n';
    }
    return 0;
}

无意中看到一个知识,此题转化更专业的叫法曼哈顿距离与切比雪夫距离的转换

F - Contrast

结论:将 B 按降序排序后,B 中最多只会有一段 B [ l ∼ r ] B[l∼r] B[lr] A [ l ∼ r ] A[l∼r] A[lr] 是相同的,且 A [ l ∼ r ] A[l∼r] A[lr] B [ l ∼ r ] B[l∼r] B[lr] 中所有值都等于同一个数 v a l val val,仔细想想便可得到此结论。
把这些相等的位置记下来,然后与其他的位置交换,此位置序还需满足 a i ≠ v a l a_i\ne val ai=val,每找到一个位置就可以交换一次,如果位置不够则不可能满足题意。
还有一个判断不满足题意的方法即统计a[]b[]每个数出现的次数cnta[]cntb[],对于每一个 i i i满足 c n t a i + c n t b i ≤ n cnta_i+cntb_i\leq n cntai+cntbin才可能构造出一组解,否则不可能满足题意。
口胡证明:对于a[]中的i需要b[]至少存在有cnta[i]个不等于i的数与之配对,即cnta[i]<=n-cntb[i],证毕。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
const int N=200010;
int a[N],b[N],n;
int main()
{
    IO;
    int T=1;
    //cin>>T;
    while(T--)
    {
        cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i];
        for(int i=1;i<=n;i++) cin>>b[i];
        reverse(b+1,b+1+n);
        vector<int> p,q;
        int val=0,cnt=0;
        for(int i=1;i<=n;i++)
        {
            if(a[i]!=b[i]) continue;
            cnt++;
            p.push_back(i);
            val=b[i];
        }
        for(int i=1;i<=n;i++)
        {
            if(!cnt) break;
            if(a[i]==b[i]) continue;
            if(a[i]!=val&&b[i]!=val)
            {
                cnt--;
                q.push_back(i);
            }
        }
        if(cnt) return cout<<"No\n",0;
        for(int i=0;i<q.size();i++) swap(b[p[i]],b[q[i]]);
        cout<<"Yes\n";
        for(int i=1;i<=n;i++) cout<<b[i]<<' ';
        cout<<'\n';
    }
    return 0;
}

ABC现在看来以及没有想象中那么难,自己现在都可以接受。
正式上课了,要加油哦~

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值