atcoder abc147

A
水题

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int a,b,c;scanf("%d%d%d",&a,&b,&c);
    if(a+b+c>=22)
        cout<<"bust"<<endl;
    else cout<<"win"<<endl;
}

B
水题

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
char s[N];
int main()
{
    scanf("%s",s+1);
    int n=strlen(s+1);
    int ans=0;
    int l=1,r=n;
    while(l<=r)
    {
        if(s[l++]!=s[r--]) ans++;
    }
    cout<<ans<<endl;
}

C
简单状压

#include<bits/stdc++.h>
using namespace std;
const int N=16;
int n;
vector<int>v[N][2];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int x;scanf("%d",&x);
        for(int j=1;j<=x;j++)
        {
            int y,z;scanf("%d%d",&z,&y);
            v[i][y].push_back(z);
        }
    }
    int ans=0;
    for(int i=0;i<1<<n;i++)
    {
        bool flag=true;
        for(int j=1;j<=n;j++)
        {
            bool f=true;
            for(int k=0;k<v[j][0].size();k++)
                if(1<<(v[j][0][k]-1)&i) f=false;
            for(int k=0;k<v[j][1].size();k++)
                if(!((1<<v[j][1][k]-1)&i)) f=false;
            if(f&&(!(1<<(j-1)&i))) flag=false;
            if(!f&&(1<<(j-1)&i)) flag=false;
        }
        if(flag) ans=max(ans,__builtin_popcount(i));
    }
    printf("%d\n",ans);
}

D
简单拆位

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3e5+5,mod=1e9+7;
int n;
ll a[N],b[60];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        for(int j=0;j<60;j++)
            if(a[i]>>j&1) b[j]++;
    }
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<60;j++)
            if(a[i]>>j&1) b[j]--;
        for(int j=0;j<60;j++)
            if(a[i]>>j&1)
        {
            ans=(ans+(1ll<<j)%mod*(n-i-b[j])%mod)%mod;
        }
        else
        {
            ans=(ans+(1ll<<j)%mod*b[j]%mod)%mod;
        }
    }
    printf("%lld\n",ans);
}

E
dp[i][j][k]表示走到格子i,j,sum1-sum2=k的状态是否存在。

dp一遍即可,用bitset优化方便又省时。

#include<bits/stdc++.h>
using namespace std;
const int N=85,low=81*81;
int a[N][N],b[N][N];
bitset<N*N*2>dp[N][N];
int mx[N][N];
int n,m;
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        scanf("%d",&a[i][j]);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        scanf("%d",&b[i][j]);
    dp[1][1].set(a[1][1]-b[1][1]+low,1);
    dp[1][1].set(b[1][1]-a[1][1]+low,1);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
    {
        if(i==1&&j==1) continue;
        int x=abs(a[i][j]-b[i][j]);
        dp[i][j]=(dp[i-1][j]<<x)|(dp[i-1][j]>>x)|(dp[i][j-1]<<x)|(dp[i][j-1]>>x);
    }
    int ans=1e9;
    for(int i=0;i<=low*2;i++)
        if(dp[n][m][i])
        {
            ans=min(ans,abs(i-low));
        }
    printf("%d\n",ans);
}

F
选定了i个x,可以决定能选多少个d,对于x和d的符号相等,设k位x和d的最小公倍数,那么加d/k个x

就要减d/x个k使得原来的值相等,那么枚举x的个数,确定选不同的d有多少方案数

然后容斥一下,假如当前有i个x,把有i+d/k个x的方案数给减去,时间复杂度O(n)。

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
typedef long long ll;
ll n,x,d;
ll ans=0,f[N],sum[N];
int main()
{
    scanf("%lld%lld%lld",&n,&x,&d);
    if(x==0&&d==0)
    {
        cout<<1<<endl;return 0;
    }
    if(x<0&&d<0)
        x*=-1,d*=-1;
    for(int i=1;i<=n;i++)
        sum[i]=sum[i-1]+i-1;
    ll k=__gcd(x,d),xx=x/k,dd=d/k;
    if(xx>=0&&dd>=0)
    {
        for(int i=0;i<=n;i++)
        {
            ll l=sum[i],r=sum[n]-sum[n-i];
            if(l>r) swap(l,r);
            ans+=r-l+1;
            if(i+dd<=n)
            {
                l=max(l,sum[i+dd]+xx);
                ans-=max(0ll,r-l+1);
            }
        }
    }
    else
    {
        if(xx<0) xx*=-1;
        if(dd<0) dd*=-1;
        for(int i=0;i<=n;i++)
        {
            ll l=sum[i],r=sum[n]-sum[n-i];
            if(l>r) swap(l,r);
            ans+=r-l+1;
            if(i+dd<=n)
            {
                r=min(r,sum[n]-sum[n-i-dd]-xx);
                l=max(l,sum[i+dd]-xx);
                ans-=max(0ll,r-l+1);
            }
        }
    }
    printf("%lld\n",ans);
}

猜你喜欢

转载自blog.csdn.net/Huah_2018/article/details/103482463