首页 > 代码库 > 2014多校联合-第八场

2014多校联合-第八场

1001:2048

很明显,一开始看错题了。。。sad

这题目我感觉挺卡时间的。。。

dp[i][j]:在选择2^i的时候,选择的和为j*2^i到(j+1)*2^i-1时候的情况。

#include <iostream>
#include<stdio.h>
#include<vector>
#include<queue>
#include<stack>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
#define LL __int64
#define lcm(a,b) (a*b/gcd(a,b))
#define mod 998244353
#define maxn 110000
//O(n)求素数,1-n的欧拉数
int num[21];
LL dp[15][2100];
LL jie[maxn];
LL use[15][2100];
int n;
int add(int x)
{
    if(x==0)return 20;
    int c=0;
    while(x!=1)
    {
        if(x&1)return 20;
        x=x>>1;
        c++;
    }
    return c;
}
LL q_mod(LL a,LL b,LL n)
{
    LL ret=1;
    LL tmp=a%n;
    while(b)
    {
        //基数存在
        if(b&0x1) ret=ret*tmp%n;
        tmp=tmp*tmp%n;
        b>>=1;
    }
    return ret;
}
LL select(int n,int m)
{
    if(m>n)return 0;
    LL ans=jie[n];
    ans=(ans*q_mod((jie[m]*jie[n-m])%mod,mod-2,mod))%mod;
    return ans;
}
void select()
{
    for(int i=1;i<=11;i++)
    {
        for(int j=0;j<2048;j++)
        {
            use[i][j]=select(num[i-1],j);
        }
    }
}
void dos()
{
    select();
    for(int j=0;j<2048;j++)dp[1][j]=use[1][j];
    for(int i=2; i<12; i++)
    {
        int cnt=1<<(12-i);
        for(int j=0; j<cnt; j++)
        {
            for(int k=0; k<=j*2+1; k+=2)
            {
                dp[i][j]+=((dp[i-1][k]+dp[i-1][k+1])*use[i][j-k/2])%mod;
            }
            dp[i][j]%=mod;
        }
    }
    LL ans=0;
    ans=q_mod(2,num[20],mod);
    LL ps=(dp[11][0]+dp[11][1])%mod;
    ps=q_mod(2,n-num[20],mod)-ps;
    ps=(ps+mod)%mod;
    ans=(ans*ps)%mod;
    cout<<ans<<endl;
}
int main()
{
    //freopen("1001.in","r",stdin);
    //freopen("10011.out","w",stdout);
    int cas=0;
    int x;
    jie[0]=1;
    for(int i=1; i<maxn; i++)jie[i]=(jie[i-1]*i)%mod;
    while(~scanf("%d",&n)&&n)
    {
        memset(num,0,sizeof(num));
        memset(dp,0,sizeof(dp));
        cas++;
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&x);
            num[add(x)]++;
        }
        printf("Case #%d: ",cas);
        dos();
    }
    return 0;
}
1004:Kingdom

超级后悔当时没有看这个题。。。。明显水题嘛。。。。

相当于拓扑排序。。

每次弹出入度最小的点。根本没有-1的情况。。。被骗了。。。

#include <iostream>
#include<stdio.h>
#include<vector>
#include<queue>
#include<stack>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
#define LL long long
#define lcm(a,b) (a*b/gcd(a,b))
//O(n)求素数,1-n的欧拉数
#define maxn 505
int mp[maxn][maxn];
vector<int>vec;
int du[maxn];
int n;
void tuopu()
{
    vec.clear();
    int i;
    while(1)
    {
        int now=0;
        int minn=9999;
        for(i=1;i<=n;i++)
        {
            if(du[i]>=0&&minn>du[i])
            {
                now=i;
                minn=du[i];
            }
        }
        if(now==0)break;
        vec.push_back(now);
        du[now]=-1;
        for(i=1;i<=n;i++)
        {
            if(mp[i][now])du[i]--;
        }
    }
    if(vec.size()<n)cout<<"-1"<<endl;
    else
    {
        for(int i=vec.size()-1;i>=0;i--)
        {
            printf("%d",vec[i]);
            if(i!=0)printf(" ");
            else puts("");
        }
    }
}
char str[11001];
int main()
{
    LL p,g,y;
   //freopen("1004.in","r",stdin);
   // freopen("10041.out","w",stdout);
    while(~scanf("%d",&n)&&n)
    {
        memset(du,0,sizeof(du));
        for(int i=1;i<=n;i++)
        {
            scanf("%s",str);
            for(int j=1;j<=n;j++)
            {
                mp[i][j]=str[j-1]-'0';
                if(mp[i][j])du[i]++;
            }
        }
        tuopu();
    }
    return 0;
}
1007:Multiplication table

整场比赛最伤的就是这个题,一开始思路有问题,后来就一直带偏了。。。

很明显,对于不同的数,首位的类别有不同种。

#include <iostream>
#include<stdio.h>
#include<vector>
#include<queue>
#include<stack>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
#define LL long long
#define lcm(a,b) (a*b/gcd(a,b))
//O(n)求素数,1-n的欧拉数
int mp[2][505][505];
vector<int>vec[505];
int ans[505];
int num[505];
int in()
{
    char ch;
    int a = 0;
    while((ch = getchar()) == ' ' || ch == '\n');
    a += ch - '0';
    while((ch = getchar()) != ' ' && ch != '\n')
    {
        a *= 10;
        a += ch - '0';
    }
    return a;
}
int main()
{
   // freopen("1007.in","r",stdin);
   // freopen("10071.out","w",stdout);
    int x,y;
    int cas=0;
    int check[101];
    int n;
    while(~scanf("%d",&n)&&n)
    {
        cas++;
        memset(ans,-1,sizeof(ans));
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                x=in();
                y=in();
                mp[0][i][j]=x;
                mp[1][i][j]=y;
                if(x==y&&x==i&&i==j)
                {
                    ans[0]=i;
                }
            }
        }
        for(int i=0; i<n; i++)
        {
            if(mp[0][i][i]==ans[0]&&mp[1][i][i]!=ans[0]&&mp[1][i][i]==i)
            {
                ans[1]=i;
                break;
            }
        }
        for(int i=0; i<n; i++)
        {
            vec[i].clear();
            for(int j=0; j<n; j++)vec[i].push_back(mp[0][i][j]);
            sort(vec[i].begin(),vec[i].end());
            num[i]=1;
            for(int j=1; j<vec[i].size(); j++)
            {
                if(vec[i][j]!=vec[i][j-1])num[i]++;
            }
            if(num[i]>1)ans[num[i]]=i;
        }
        printf("Case #%d:",cas);
        int leap=0;
        for(int i=0; i<n; i++)
        {
            printf(" %d",ans[i]);
            if(ans[i]==-1)leap=1;
        }
        while(leap)
        {
            cout<<check[110101010110]<<endl;
        }
        cout<<endl;
    }
    return 0;
}