2016 百度之星 初赛(2A)

来源:互联网 发布:python基础书籍知乎 编辑:程序博客网 时间:2024/05/29 11:21

【A】All X

【题目链接】点击打开链接

【解题思路】懂了(a/b)%mod = (a)%(b*mod)/b%mod,这个之后,这题完全就是水题。。。

【AC代码】

#include <queue>#include <stdio.h>#include <string.h>#include <iostream>using namespace std;#define ll long longll pow(ll a,ll n,ll mod){    ll res=1;    ll temp=a;    while(n){        if(n&1) res=res*temp%mod;        temp=((temp%mod)*(temp%mod))%mod;        n>>=1;    }    return res;}int main(){    int T;    ll x,m,k,c;    scanf("%d",&T);    for(int i=1; i<=T; i++){        scanf("%I64d%I64d%I64d%I64d",&x,&m,&k,&c);        ll ans=(pow(10,m,9*k)*x)%(9*k)-x;        printf("Case #%d:\n",i);        if(ans==9*c) puts("Yes");        else         puts("No");    }    return 0;}

【B】Sitting in Line

【题目链接】点击打开链接

【解题思路】简单状压dp,dp【i】【j】代表当前状态为i的时候,以a[j]结尾的a1*a2+a2*a3+a3*a4+...an-1*an的最大值。

【状态转移】dp[i|(1<<k)][k]=min(dp[i|(1<<k)][k],dp[i][j]+a[j]*a[k])

【AC代码】

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;const int N=16;const int INF=0x3f3f3f3f;int a[N],p[N],dp[1<<N][N];//状态为i,以a[j]结尾的最大的积int n;int main(){    int T,cas;    scanf("%d",&T);    for(cas=1; cas<=T; cas++){        scanf("%d",&n);        for(int i=0; i<n; i++){            scanf("%d%d",&a[i],&p[i]);        }        //INIT 1.        for(int i=0; i<(1<<n); i++)            for(int j=0; j<n; j++)                dp[i][j]=-INF;        //INIT 2.        for(int i=0; i<n; i++)            if(p[i]==0||p[i]==-1) //当p[i]==0或者p[i]==-1才可以初始化                dp[1<<i][i]=0;        //DP        for(int s=0; s<(1<<n); s++){            for(int i=0; i<n; i++){                if(dp[s][i]!=-INF){                    for(int k=0; k<n; k++){//当是第p[k]个或者p[k]==-1的时候可以往里面放                        if(((s&(1<<k))==0&&(p[k]==__builtin_popcount(s)||p[k]==-1)))                            dp[s|(1<<k)][k]=max(dp[s|(1<<k)][k],dp[s][i]+a[i]*a[k]);                    }                }            }        }        //get ans.        int ans=-INF;        for(int i=0; i<n; i++){            ans=max(ans,dp[(1<<n)-1][i]);        }        printf("Case #%d:\n",cas);        printf("%d\n",ans);    }    return 0;}

【F】BD String.

【题目链接】点击打开链接

【解题思路】规律和递归!

从字符串规则可以看出以下几点

①S(n)的串长度为;

②S(n)中B的个数为个(以正中间的B为中心,假设左边有x个B,那么右边有个,即左边B的个数+右边B的个数=S(n-1)的串长度)

远大于,故只是吓唬我们的

由上述几点可知,此题并没有表面上那么吓人

要求区间[l,r]内B的个数,我们可以转化为求[1,r]-[1,l-1]

而求区间[1,x]内B的个数,又可以如上述第②条所说,拆成3段,递归求解

比如x=12时,S=BBDBBDDBBBDD……

拆成3段如下:

右边4个是多余的,但是因为右边是由reverse+flip得到的,求右边4个中B的个数可以转化成求4-([1,7]中B的个数-[1,3]中B的个数)

而[1,3]中的个数又是得递归求解的

【AC代码】

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;#define ll long longll l,r;//2^n==x.ll solve(ll x){    if(x==0) return 0;    ll m=0;    ll ans;    while(m<x) m=m*2+1;    m=(m-1)/2;    ans=(m+1)/2;    ll curlen=x-m-1;    return ans+1+curlen-(ans-solve(m-curlen));}int main(){    int T;    scanf("%d",&T);    while(T--){        scanf("%I64d%I64d",&l,&r);        ll ans=solve(r)-solve(l-1);        printf("%I64d\n",ans);    }    return 0;}

【G】 Gym Class

【题目链接】点击打开链接

【解题思路】拓扑排序+贪心

众所周知,为了使每个人给的评分尽可能高,在没有条件的情况下,必定是ID高的排前面来得最优

但是度度熊没有那么善良

ID为B的同学不能排在A前面,好吧,怎么做呢?

对于这种调度问题,我们不妨用拓扑排序来求解

假设B不能排在A前面,那么我就在AB之间画一条从A指向B的边,那么我们可以得到一幅有向图

我们要按ID从大往小排,同时要考虑当前这位同学是否有特殊要求

上面有向图中,凡入度为0的结点,表示没有同学不希望该同学排在它的前面,故该同学可以按照ID从大往小排

所以此题的做法是,每次将入度为0的结点放入优先队列中,选取ID最大的结点先排,然后将该ID的同学讨厌的所有同学入度-1,若入度变为0同样要放入优先队列判断ID先后,这里建图可以邻接表实现,也可以利用一些vector


【AC代码】

#include <queue>#include <stdio.h>#include <string.h>#include <iostream>using namespace std;#define ll long longconst int inf=0x3f3f3f3f;struct cmp{   bool operator()(int &a,int &b){       return a<b;   }};int n,m;int in[100005];//记录入度priority_queue<int,vector<int>,cmp>pq;//最大值优先vector<int>v[100005];//存图int main(){    int T;    int x,y;    scanf("%d",&T);    while(T--){        ll ans=0;        int minid=inf;        scanf("%d%d",&n,&m);        memset(in,0,sizeof(in));        for(int i=1; i<=n; i++) v[i].clear();        while(!pq.empty())      pq.pop();        for(int i=0; i<m; i++){            scanf("%d%d",&x,&y);            in[y]++;            v[x].push_back(y);        }        for(int i=1; i<=n; i++){            if(!in[i]) pq.push(i);        }        while(!pq.empty()){            int temp=pq.top();            pq.pop();            minid=min(minid,temp);            ans+=minid;            for(int i=0; i<v[temp].size(); i++){                in[v[temp][i]]--;                if(in[v[temp][i]]==0) pq.push(v[temp][i]);            }        }        printf("%lld\n",ans);    }    return 0;}


0 0
原创粉丝点击