• 【LGR-063】洛谷11月月赛 I & MtOI2019 Ex Div.2


    [MtOI2019]黑蚊子多

    送分向水题,直接模拟即可。

     1 #include<iostream>
     2 #include<cstdio>
     3 #define N 1505
     4 using namespace std;
     5 int n,m,k,a[N],now,ans,hve[N];
     6 int main()
     7 {
     8     cin>>n>>m>>k;
     9     for(int i=1;i<=k;i++)cin>>a[i],hve[a[i]]=1;
    10     while(now<n)
    11     {
    12         ans++;
    13         now+=m;
    14         if(hve[now])m++;
    15     } 
    16     cout<<ans<<endl;
    17     return 0;
    18 } 

    [MtOI2019]膜Siyuan

    枚举$x,y$,根据$xor$的性质算出z。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #define N 2005
     6 using namespace std;
     7 int n,m,a[N],b[N],c[N],ans;
     8 int main()
     9 {
    10     //freopen("1.in","r",stdin);
    11     //freopen("1.out","w",stdout);
    12     cin>>n>>m;
    13     for(int i=1;i<=n;i++)cin>>a[i]>>b[i]>>c[i];
    14     for(int x=1;x<=m;x++)
    15     {
    16         for(int y=1;y<=m;y++)
    17         {
    18             int z=((abs(a[1]-x)^abs(b[1]-y)^9)),f=0;
    19             //a^b=c
    20             //abs(a[1]-x)^abs(b[1]-y)^z=9
    21             int zz=c[1]-z;
    22             if(zz>m||zz<=0)f=1;
    23             for(int i=1;i<=n;i++)
    24             {
    25                 if((abs(a[i]-x)^abs(b[i]-y)^abs(c[i]-zz))!=9)f=1;
    26             }
    27             if(!f)ans++;
    28             int ff=0,_zz=c[1]+z;
    29             if(_zz>m||_zz<=0||zz==_zz)ff=1;
    30             for(int i=1;i<=n;i++)
    31             {
    32                 if((abs(a[i]-x)^abs(b[i]-y)^abs(c[i]-_zz))!=9)ff=1;
    33             }
    34             if(!ff)ans++;
    35         }
    36     }
    37     cout<<ans<<endl;
    38     return 0;
    39 }

    [MtOI2019]时间跳跃

    考试时写了50分做法,枚举每一个边选或不选,然后判断是否是凸多边形,判断一些边能否组成凸多边形很简单,看一下是否出最大值外的权值和是否大于最大值即可。

    50分代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #define int long long
     5 #define N 5005
     6 #define p (long long)(1e9+7)
     7 using namespace std;
     8 int T,n,ans,a[N];
     9 int ksm(int a,int b)
    10 {
    11     int r=1;
    12     while(b)
    13     {
    14         if(b&1)r*=a,r%=p;
    15         a*=a;a%=p;
    16         b>>=1;
    17     }
    18     return r;
    19 }
    20 void dfs(int t,int sum,int maxn,int tot)
    21 {
    22     if(t==n+1)
    23     {
    24         if(maxn<sum-maxn)
    25         {
    26             ans+=tot;
    27             ans%=p;
    28         }
    29         return;
    30     }
    31     a[t]=0;
    32     dfs(t+1,sum,maxn,tot);
    33     a[t]=1;
    34     dfs(t+1,sum+t,t,tot+1);
    35 }
    36 signed main()
    37 {
    38     cin>>T;
    39     while(T--)
    40     {
    41         cin>>n;ans=0;
    42         dfs(1,0,0,0);
    43         cout<<(ans*ksm((1<<n),p-2))%p<<endl;
    44     }
    45 }

    满分做法是$DP$。

    设$f_i$为选出边长和为$i$的不合法方案数

    设$w_i$为选出边长和为$i$的不合法权值和

    对于$f$的转移,直接背包即可。

    对于$w$的转移: 我们考虑加入一条长度$i$的边加入边集,那么如果是从$w[j-i]$转移到 $w[j]$, 那么就会在$w[j-i]$的所有状态的边集中加入一条长度为$i$的边然后考虑的不同的边集个数是$f[j-i]$那么在每一个边集中加入一条边的权值和, 就等价于在原本的权值和的基础上加上等同于边集的个数。

    然后从小到大枚举并且累加答案即可。

    100分代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define N 5005
    #define int long long
    #define p (long long)(1e9+7)
    using namespace std;
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*f;
    }
    int ksm(int a,int b)
    {
        int r=1;
        while(b)
        {
            if(b&1)r*=a,r%=p;
            a*=a;a%=p;
            b>>=1;
        }
        return r;
    }
    int T,n,f[N],w[N],s[N];
    void init(int n)
    {
        f[0]=1;
        for(int i=1;i<=n;i++)
        {
            s[i]=s[i-1];
            for(int j=0;j<=i;j++)s[i]=(s[i]+f[j]+w[j])%p;
            for(int j=n;j>=i;j--)f[j]=(f[j]+f[j-i])%p,w[j]=(w[j]+f[j-i]+w[j-i])%p;
        }
    }
    signed main()
    {
        T=read();
        init(N-5);
        while(T--)
        {
            n=read();
            int xx=ksm(ksm(2,n),p-2)%p,xxx=1ll*n*ksm(2,n-1)%p;
            cout<<(xx*(((xxx-s[n])%p)+p)%p)%p<<endl;
        }
    }

    [MtOI2019]恶魔之树

    等我看懂题解......

  • 相关阅读:
    解决margin 外边距合并问题
    tsx 校验 以及写法
    tsx 引入文件找不到
    Ubuntu 16.04安装和卸载软件命令
    Java8 中使用Stream 让List 转 Map使用总结
    Java8 Stream流式编程浅析
    浅析IOC 和 DI
    [ Java面试题 ]Java 开发岗面试知识点解析
    Intellij Idea 常用快捷键总结+实用小技巧
    Intellij Idea基础设置
  • 原文地址:https://www.cnblogs.com/szmssf/p/11789440.html
Copyright © 2020-2023  润新知