2014多校聯合第一場

1001:Couple doubi

暴力打表找規律可知,對於任意的p。

(1^i+2^i+...+(p-1)^i)%p={    

非0     ,i%(p-1)==0

 0        ,  i%(p-1)!=0

所以,結果就很顯然了。

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
using namespace std;
#define eps 1e-4
#define zero(x) ((fabs(x)<eps)?0:x)
int main()
{
    int n,k;
    while(~scanf("%d%d",&n,&k))
    {
        int x=n/(k-1);
        if(x%2==0)cout<<"NO"<<endl;
        else cout<<"YES"<<endl;
    }
    return 0;
}

1004:Task

很顯然,y對總值的影響遠小於x。

所以:

按y排序,y小的放在前面,然後按x排序,x小的放在前面,然後按屬性排序,任務放在前面。

然後依次遍歷這些點。

如果當前點爲任務:

把當前任務的價值放入set中。

如果當前點爲機器:

在set中尋找最後一個比當前機器的價值小的任務。

#include <iostream>
#include<stdio.h>
#include<set>
#include<vector>
#include<algorithm>
using namespace std;
#define LL long long
struct list
{
    int x;
    int y;
    int s;
    int leap;
    friend bool operator <(const list &a,const list &b)
    {
        if(a.y!=b.y)return a.y<b.y;
        else if(a.x!=b.x)return a.x<b.x;
        else return a.leap<b.leap;
    }
}node[220000];
multiset<int>st;
multiset<int>::iterator it;
int sea(int x)
{
    if(st.size()==0)return 0;
    it=st.begin();
    if(x<(*it))return 0;
    it=st.lower_bound(x);
    if(it==st.end())
    {
        it=st.end();
        it--;
        int ans=(*it);
        st.erase(it);
        return ans;
    }
    if((*it)==x)
    {
        st.erase(it);
        return x;
    }
    it--;
    int ans=(*it);
    st.erase(it);
    return ans;
}
void dos(int n)
{
    int x=0;
    LL sum=0;
    st.clear();
    for(int i=1;i<=n;i++)
    {
        if(node[i].leap==1)
        {
            int res=sea(node[i].s);
            if(res)
            {
                x++;
                sum+=(LL)res;
            }
        }
        else
        {
            st.insert(node[i].s);
        }
    }
    cout<<x<<" "<<sum<<endl;
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&node[i].x,&node[i].y);
            node[i].leap=1;
            node[i].s=node[i].x*500+node[i].y*2;
        }
        for(int i=n+1;i<=n+m;i++)
        {
            scanf("%d%d",&node[i].x,&node[i].y);
            node[i].leap=0;
            node[i].s=node[i].x*500+node[i].y*2;
        }
        sort(node+1,node+n+m+1);
        for(int i=1;i<=n+m;i++)
        {
            //cout<<node[i].x<<" "<<node[i].y<<" "<<node[i].leap<<endl;
        }
        dos(n+m);
    }
    return 0;
}

1005:Peter's Hobby

wh[i][j]:天氣爲i,葉子的狀態爲j的概率。

ww[i][j]:今天天氣爲i,明天天氣爲j的概率。

st[i]:第一天天氣爲i的概率。

葉子的狀態序列爲{b1,b2...bn}

那麼對於某個天氣序列{a1,a2....an}的概率爲:

st[a1]*wh[a1][b1]* ww[a1][a2] *wh[a2][b2]* ww[a2][a3]* wh[a3][b3]*........*ww[an-1][an]*wh[an][bn];

因爲結果有可能很小,所以用log把乘法轉化爲加法。

然後就是很明顯的dp求路徑了。。。。

#include <iostream>
#include<stdio.h>
#include<set>
#include<vector>
#include<math.h>
#include<algorithm>
#include<string.h>
using namespace std;
#define LL long long
#define INF 99999999
#define eps 1e-6
#define zero(x) ((fabs(x)<eps)?0:x)
double wh[3][4]={
    {0.6,0.2,0.15,0.05},
    {0.25,0.3,0.2,0.25},
    {0.05,0.10,0.35,0.5}
};
double ww[3][3]={
    {0.5,0.375,0.125},
    {0.25,0.125,0.625},
    {0.25,0.375,0.375}
};
double st[3]={0.63,0.17,0.2};
double dp[55][3];
double ans[55][3];
vector<int>vec;
int a[110];
char str[110];
void dfs(int x,int y)
{
    //cout<<y<<endl;
    vec.push_back(y);
    if(x==1)
    {
        return ;
    }
    for(int i=2;i>=0;i--)
    {
        if(zero(ans[x][y]-(ans[x-1][i]+dp[x][y]+ww[i][y]))==0)
        {
            dfs(x-1,i);
            break;
        }
    }
}
int main()
{
    int T,cas,n;
    scanf("%d",&T);
    cas=0;
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<3;j++)
        {
            ww[i][j]=log(ww[i][j]);
        }
    }
    while(T--)
    {
        vec.clear();
        cas++;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",str);
            int x=strlen(str);
            if(x==3)a[i]=0;
            else if(x==6)a[i]=1;
            else if(x==4)a[i]=2;
            else if(x==5)a[i]=3;
        }
        memset(dp,0,sizeof(dp));
        double s=0;
        for(int i=1;i<=n;i++)
        {
            s=0;
            for(int j=0;j<3;j++)
            {
                dp[i][j]=wh[j][a[i]];
                s+=dp[i][j];
            }
            for(int j=0;j<3;j++)dp[i][j]=dp[i][j]/s;
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<3;j++)
            {
                dp[i][j]=log(dp[i][j]);
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<3;j++)ans[i][j]=-INF;
        }
        for(int j=0;j<3;j++)
        {
            ans[1][j]=dp[1][j]+log(st[j]);
        }
        for(int i=2;i<=n;i++)
        {
            for(int j=0;j<3;j++)
            {
                for(int k=0;k<3;k++)
                {
                    double ps=ans[i-1][k]+ww[k][j]+dp[i][j];
                    ans[i][j]=max(ans[i][j],ps);
                }
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<3;j++)
            {
               // cout<<ans[i][j]<<" ";
            }
         //   cout<<endl;
        }
        double maxx=-INF;
        int p=0;
        for(int j=0;j<3;j++)
        {
            if(maxx<ans[n][j])
            {
                maxx=ans[n][j];
                p=j;
             //   cout<<maxx<<" "<<p<<endl;
            }
        }
        dfs(n,p);
        printf("Case #%d:\n",cas);
        for(int i=n-1;i>=0;i--)
        {
            if(vec[i]==0)puts("Sunny");
            if(vec[i]==1)puts("Cloudy");
            if(vec[i]==2)puts("Rainy");
        }
    }
    return 0;
}
1009:Turn the pokers

假如初始全部是正面(狀態爲0)。

全部操作完成後,正面的個數爲x個。

那麼x有很多種情況。假如分別爲{x1,x2....xk}

那麼結果爲C(m,x1)+C(m,x2)+C(m,x3)+...+C(m,xk).

很明顯可以得知x1,x2...xk奇偶性一致。

我們試驗幾組例子可知,x1,x2...xk是一段連續的區間。

那麼我們只需要求出x1,xk就可以了。

然後我們就可以每走一步,根據上一步的x1,xk,確定這一步之後的x1,xk.

#include <iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
using namespace std;
#define LL long long
#define mod 1000000009
LL jie[110000];
void init()
{
    jie[0]=1;
    jie[1]=1;
    for(int i=2;i<=100000;i++)
    {
        jie[i]=jie[i-1]*i;
        jie[i]=jie[i]%mod;
    }
}
LL qmod(LL x,LL y)
{
    if(y==0)return 1;
    if(y==1)return x%mod;
    LL ans=qmod(x,y/2);
    ans=(ans*ans)%mod;
    if(y%2)ans=(ans*x)%mod;
    return ans;
}
LL dos(int n,int m)
{
    LL ans=jie[n];
    ans=(ans*qmod((jie[m]*jie[n-m])%mod,mod-2))%mod;
    return ans;
}
int main()
{
    init();
    int n,m,x;
    while(~scanf("%d%d",&n,&m))
    {
        int l,r;
        scanf("%d",&x);
        l=r=x;
        int ll,rr;
        for(int i=2;i<=n;i++)
        {
            scanf("%d",&x);
            ll=l-x;
            rr=r+x;
            if(ll<0)
            {
                if(r-x<0)ll=0+x-r;
                else ll=((l-x)%2+2)%2;
            }
            if(rr>m)
            {
                if(l+x<=m)rr=m-(r+x)%2;
                else rr=m-(l+x-m);
            }
            l=ll;
            r=rr;
        }
        LL ans=0;
        for(int i=l;i<=r;i+=2)
        {
            ans+=dos(m,i);
            ans=ans%mod;
        }
        cout<<ans<<endl;
    }
    return 0;
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章