zoukankan      html  css  js  c++  java
  • Gym

    A - The game of Osho

    题意:每次给你G堆石子,每堆有(n{_i})个,一次可挑走(B{_i}^k)个。最后不能选的人输。问最后先手赢还是后手赢。

    思路:从SG表的方式入手。
    (B{_i})为奇数时,任意次幂也为奇数,此时若n为奇数,那么第一个人拿走若干后一定剩下是偶数个,第二个人再拿剩下的肯定是奇数个。以此类推此时永远是第一个人拿完后是偶数,所以最后拿到0的那一步也是第一个人拿走的,此时先手必胜。反之后手必胜。所以sg = n&1。
    (B{_i})为偶数时,(B^k) = ((B+1 -1)^k),展开后对(B+1)取余,只有1和B两种情况(二项展开式的第一项为1或-1),那么n可以看出n = k*(B+1) + T, 0<=T<=B,若T小于B,只和T奇偶性有关。若T等于B,画一下sg函数可以知道此时sg为2(两个后继0和B-1,sg分别是0和1)。
    最后依照上述判别方式将sg异或起来即可判断。

    view code
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<map>
    #include <queue>
    #include<sstream>
    #include <stack>
    #include <set>
    #include <bitset>
    #include<vector>
    #define FAST ios::sync_with_stdio(false)
    #define abs(a) ((a)>=0?(a):-(a))
    #define sz(x) ((int)(x).size())
    #define all(x) (x).begin(),(x).end()
    #define mem(a,b) memset(a,b,sizeof(a))
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define rep(i,a,n) for(int i=a;i<=n;++i)
    #define per(i,n,a) for(int i=n;i>=a;--i)
    #define endl '
    '
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> PII;
    const int maxn = 1e5+200;
    const int inf=0x3f3f3f3f;
    const double eps = 1e-7;
    const double pi=acos(-1.0);
    const int mod = 1e9+7;
    inline int lowbit(int x){return x&(-x);}
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
    inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
    inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
    inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
    inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
    int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
    
    ll sg[105];
    vector<ll> f;
    ll n, b;
    
    int main()
    {
        freopen("powers.in","r",stdin);
        int kase;
        cin>>kase;
        while(kase--)
        {
            int G = read();mem(sg,0);
            rep(i,1,G)
            {
                b = read(), n = read();
                if(b&1) sg[i] = n&1;
                else
                {
                    ll m = n%(b+1);
                    if(m==b) sg[i] = 2;
                    else sg[i] = m&1;
                }
            }
            ll ans = 0;
            rep(i,1,G) ans ^= sg[i];
            puts(ans?"1":"2");
        }
        return 0;
    }
    
    

    D - Popcorn

    排列组合签到题

    view code
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<map>
    #include <queue>
    #include<sstream>
    #include <stack>
    #include <set>
    #include <bitset>
    #include<vector>
    #define FAST ios::sync_with_stdio(false)
    #define abs(a) ((a)>=0?(a):-(a))
    #define sz(x) ((int)(x).size())
    #define all(x) (x).begin(),(x).end()
    #define mem(a,b) memset(a,b,sizeof(a))
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define rep(i,a,n) for(int i=a;i<=n;++i)
    #define per(i,n,a) for(int i=n;i>=a;--i)
    #define endl '
    '
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> PII;
    const int maxn = 1e5+200;
    const int inf=0x3f3f3f3f;
    const double eps = 1e-7;
    const double pi=acos(-1.0);
    const int mod = 1e9+7;
    inline int lowbit(int x){return x&(-x);}
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
    inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
    inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
    inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
    inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
    int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
    
    inline ll C(ll n,ll m){return (ll)round(tgamma(n+1)/tgamma(m+1)/tgamma(n-m+1));}
    int main()
    {
        freopen("popcorn.in", "r", stdin);
        int kase;
        cin>>kase;
        while(kase--)
        {
            ll n = read(), m = read();
            cout<<C(n,m)<<endl;
        }
        return 0;
    }
    
    

    E - Jumping

    题意:给你n个数,每个a[i]代表可以由i移动到(i-a[i])或者(i+a[i]),然后让你输出每个点到n点的最小跳跃次数。

    思路:这个题当成最短路做就是模板题。在每个点可以移动到(i-a[i])或者(i+a[i]),那就让i和这两个点建反向边,权值为1,然后跑一个以n为起始点的最短路,采用Dijkstra堆优化,然后输出每个d[i]即可。

    view code
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<map>
    #include <queue>
    #include<sstream>
    #include <stack>
    #include <set>
    #include<vector>
    #define FAST ios::sync_with_stdio(false)
    #define abs(a) ((a)>=0?(a):-(a))
    #define sz(x) ((int)(x).size())
    #define all(x) (x).begin(),(x).end()
    #define mem(a,b) memset(a,b,sizeof(a))
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define rep(i,a,n) for(int i=a;i<=n;++i)
    #define per(i,n,a) for(int i=n;i>=a;--i)
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define endl '
    '
    using namespace std;
    typedef pair<int,int> PII;
    typedef long long ll;
    const int maxn = 1e6+5;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const double eps = 1e-7;
    const double pi=acos(-1.0);
    const int mod = 1e9+7;
    inline int lowbit(int x){return x&(-x);}
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
    inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
    inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
    inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
    inline ll read(){ ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') ch = getchar();while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x; }
    int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
    const int V = 2e5, E=2e5;
    ll d[V],cost[E];
    ll n,m;
    ll head[V],pnt[E],nxt[E],e=1;
    ll vis[V];
    ll a[V];
    
    inline void addedge(ll u,ll v,ll c)
    {
        pnt[e]=v;       //当前以u为顶点,c为边长的,到v的一条边
        cost[e]=c;      //存入当前边权值
        nxt[e]=head[u];     //下一个其实是前一个
        head[u]=e++;        //当前边编号
    }
    
    inline void Dijkstra(ll s)
    {
        //mem(d,inf); mem(vis,0);
        priority_queue<PII, vector<PII>, greater<PII> > q;
        d[s] = 0;
        q.push(mp(0LL,s));
        while(!q.empty())
        {
            ll x = q.top().se; q.pop();
            if(vis[x]) continue;
            vis[x] = 1;
            for(int i=head[x];i;i = nxt[i])
            {
                ll v = pnt[i];
                if(d[v]>d[x]+cost[i]&&!vis[v])
                {
                    d[v] = d[x] + cost[i];
                    q.push(mp(d[v], v));
                }
            }
        }
    }
    
    int main()
    {
        freopen("jumping.in", "r", stdin);
        int kase;
        scanf("%d",&kase);
        while(kase--)
        {
            e = 1;
            n = read();
            rep(i,1,n) d[i] = inf, vis[i] = 0, head[i] = 0;
            rep(i,1,n)
            {
                ll d = read();
                ll x = i;
                if(x+d<=n)
                addedge(x+d,x,1);
                if(x-d>0)
                addedge(x-d,x,1);
            }
            Dijkstra(n);
            rep(i,1,n) if(d[i]!=inf) cout<<d[i]<<endl; else cout<<-1<<endl;
        }
        return 0;
    }
    

    G - The Galactic Olympics

    题意:k种物品放进n个空位里,每个空位只能放一个物品,每种物品可以放到多个空位里,问每种物品都有放置且最后n个空位都放满的方案数有多少种

    思路:考点是第二类斯特林数。
    在k大于n的时候是没有方案数的。
    其他情况下。我们考虑,如果是对每个人去选要去的空位,会产生很多重复的地方。
    因为这里n是大于等于k的,所以考虑把n个物品分配给k个人。我们先把n个物品分成k组,然后再分步相乘,乘上k组的排列即可。
    比如k=2, n=4, 我们可以先将4分成2两组,有
    1 3
    2 2
    的搭配,方案数数是(C{_4 ^3})+(C{_4 ^2})/2 = 7,再乘上两组间调换位置,全排列(A{_2}^2)等于14。
    但是当分组变得更多的时候呢,这个时候方案数就不好一下子确定了,所以引进第二类斯特林数。
    采用递推式
    (Y[i][j] = Y[i-1][j-1] + j*Y[i-1][j])即可求得,其中Y[i][j]代表对i个数分成j组。记得最后乘上k的全排列。

    view code
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<map>
    #include <queue>
    #include<sstream>
    #include <stack>
    #include <set>
    #include <bitset>
    #include<vector>
    #define FAST ios::sync_with_stdio(false)
    #define abs(a) ((a)>=0?(a):-(a))
    #define sz(x) ((int)(x).size())
    #define all(x) (x).begin(),(x).end()
    #define mem(a,b) memset(a,b,sizeof(a))
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define rep(i,a,n) for(int i=a;i<=n;++i)
    #define per(i,n,a) for(int i=n;i>=a;--i)
    #define endl '
    '
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> PII;
    const int maxn = 1e5+200;
    const int inf=0x3f3f3f3f;
    const double eps = 1e-7;
    const double pi=acos(-1.0);
    const int mod = 1e9+7;
    inline int lowbit(int x){return x&(-x);}
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
    inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
    inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
    inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
    inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
    int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
    
    ll Y[1005][1005];
    
    
    int main()
    {
        freopen("galactic.in","r", stdin);
        int kase;
        cin>>kase;
        while(kase--)
        {
            ll n = read(), m = read();
            if(m > n) cout<<0<<endl;
            else
            {
                Y[0][0] = 1;
                rep(i,1,n) rep(j,1,m) Y[i][j] = (Y[i-1][j-1] + (j*Y[i-1][j]))%mod;
                ll ans = 1;
                rep(i,1,m) ans = (ans%mod*i%mod)%mod;
                ans = (ans%mod * Y[n][m]%mod)%mod;
                cout<<ans<<endl;
            }
        }
        return 0;
    }
    
    

    H - Commandos

    dp模板题,当前状态可以由题中三个状态转移过来。从楼层从上到下dp一遍,最后在底层找最大即可。

    view code
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<map>
    #include <queue>
    #include<sstream>
    #include <stack>
    #include <set>
    #include <bitset>
    #include<vector>
    #define FAST ios::sync_with_stdio(false)
    #define abs(a) ((a)>=0?(a):-(a))
    #define sz(x) ((int)(x).size())
    #define all(x) (x).begin(),(x).end()
    #define mem(a,b) memset(a,b,sizeof(a))
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define rep(i,a,n) for(int i=a;i<=n;++i)
    #define per(i,n,a) for(int i=n;i>=a;--i)
    #define endl '
    '
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> PII;
    const int maxn = 1e5+200;
    const int inf=0x3f3f3f3f;
    const double eps = 1e-7;
    const double pi=acos(-1.0);
    const int mod = 1e9+7;
    inline int lowbit(int x){return x&(-x);}
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
    inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
    inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
    inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
    inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
    int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
    
    ll dp[20][20][20];
    ll f[20][20][20];
    
    int main()
    {
        freopen("commandos.in", "r", stdin);
        int kase;
        cin>>kase;
        while(kase--)
        {
            mem(f,0); mem(dp,0);
            ll n = read();
            rep(i,1,n)
            {
                ll x = read(), y = read(), z = read();
                f[x][y][z] = read();
            }
            per(x,10,1) rep(y,1,10) rep(z,1,10) dp[x][y][z] = max(max(dp[x+1][y][z], dp[x][y-1][z]), dp[x][y][z-1]) + f[x][y][z];
            ll ans = 0;
            rep(y,1,10) rep(z,1,10) ans = max(dp[1][y][z], ans);
            cout<<ans<<endl;
        }
    
        return 0;
    }
    

  • 相关阅读:
    postgresql批量删除表
    Oracle迁移至PostgreSQL工具之Ora2Pg
    postgresql获取表最后更新时间(通过发布订阅机制将消息发送给应用程序)
    postgresql获取表最后更新时间(通过表磁盘存储文件时间)
    postgresql获取表最后更新时间(通过触发器将时间写入另外一张表)
    postgresql源码编译安装(centos)
    Java 学习笔记(7)——接口与多态
    Java 学习笔记(6)——继承
    Java 学习笔记(4)——java 常见类
    Java 学习笔记(4)——面向对象
  • 原文地址:https://www.cnblogs.com/Bgwithcode/p/13835990.html
Copyright © 2011-2022 走看看