2016"百度之星" - 初赛(Astar Round2A)题解

  • All X
  • Sitting in Line
  • BD String
  • Gym Class

All X

F(x,m) 代表一个全是由数字x组成的m位数字。请计算,以下式子是否成立:
F(x,m) mod k  c

1x9,1m1010
0c<k10,000

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iomanip> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) 
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (9973)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
#define MAXN (10000+10)
int h[MAXN];
int b[MAXN]; 
int cir[MAXN]={0};
int main()
{
// freopen("A.in","r",stdin);
// freopen(".out","w",stdout);
    int T=read();
    int x;
    ll m;
    int k,c;
    For(kcase,T) {
        scanf("%d%I64d%d%d",&x,&m,&k,&c);
        printf("Case #%d:\n",kcase);

        Rep(i,k) h[i]=(i*10+x)%k;

        if (k==1) {
            if (c==0) {
                puts("Yes");
            }
            else puts("No");

            continue;
        } 
        MEM(b)
        int len=1;
        cir[1]=x%k; b[cir[1]]=1;
        while(1) {
            cir[len+1]=h[cir[len]];
            if (b[cir[len+1]]) break;
            b[cir[len+1]]=len+1;
            len++;
        }
        int ans=0; 
        int hea=b[cir[len+1]];

        if (m<=len) ans=cir[m];
        else {
            m-=len;
            m%=(len-hea+1);
            cir[hea-1]=cir[len];
            ans=cir[m+hea-1];
        }

        if (ans==c) puts("Yes");
            else    puts("No");


    }   


    return 0;
}

Sitting in Line

N<=16个整数将会做成一排,通过不断交换自己的位置,达到所有相邻两数乘积的和最大的目的,规定某些数字只能在坐固定的位置上,没有被限制的数字则可以自由地交换位置。

状态压缩DP

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iomanip> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) 
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (9973)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
ll f[17][1<<17];
int a[17],n,p[17];
int c[17];
int p2[17]={0};
int calc(int x) {
    int p=0;
    while(x) p+=x%2,x/=2;
    return p;
}
int main()
{
// freopen("b.in","r",stdin); 
// freopen(".out","w",stdout);
    int T=read();
    p2[0]=1;
    For(i,16) p2[i]=p2[i-1]<<1;
    For(kcase,T) {
        printf("Case #%d:\n",kcase);
        MEMi(f) 
        n=read();
        int q=0;
        Rep(i,n) c[i]=-1;
        Rep(i,n) {
            a[i]=read(),p[i]=read();
            if (p[i]!=-1) c[p[i]]=i,q|=(1<<p[i]);
        }

        if (c[0]==-1) {
            Rep(i,n) if (p[i]==-1) f[i][p2[i]]=0; 
        }
        else f[c[0]][p2[c[0]]]=0;

        For(j,(1<<n)-2) {
            int siz=calc(j);

            Rep(i,n) {
                if (f[i][j]<-10000000000LL) continue;

                Rep(k,n) {
                    if (p2[k]&j) continue;

                    int j2=p2[k]|j;

                    if (c[siz]!=-1&&c[siz]!=k) continue;


                    f[k][j2]=max(f[k][j2],f[i][j]+(ll)a[i]*a[k]);

                }

            }   
        }

        ll x=f[0][(1<<n)-1];
        For(i,n-1) x=max(x,f[i][(1<<n)-1]) ;
        cout<<x<<endl;
    }   

    return 0;
}

BD String

众所周知,度度熊喜欢的字符只有两个:B和D。

今天,它发明了一种用B和D组成字符串的规则:

S(1)=B

S(2)=BBD

S(3)=BBDBBDD

S(n)=S(n1)+B+reverse(flip(S(n1))

其中, reverse(s) 指将字符串翻转,比如 reverse(BBD)=DBB flip(s) 指将字符串中的 B 替换为 D D 替换为 B ,比如 flip(BBD)=DDB

虽然度度熊平常只用它的电脑玩连连看,这丝毫不妨碍这台机器无与伦比的运算速度,目前它已经算出了 S(21000) 的内容,但度度熊毕竟只是只熊,一次读不完这么长的字符串。它现在想知道,这个字符串的第 L 位(从1开始)到第 R 位,含有的 B 的个数是多少?

每组数据包含两个数 L R(1LR1018)

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#include<iomanip> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) 
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (9973)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
ull t[100]={0},p2[100]={0};   
ull f(ll len) {
    if (len==0) return 0;
    int p=0;
    while (p2[p]-1<len) ++p;
    ull ans=t[p];

    ll c=p2[p]-1-len;

    ans-=c-f(c);
    return ans;
}
int main()
{
// freopen("E.in","r",stdin);
// freopen(".out","w",stdout);
    p2[0]=1;
    Fork(i,1,64) p2[i]=p2[i-1]<<1LL; 

    t[1]=1;
    Fork(i,2,63) t[i]=t[i-1]*2LL;

    int T=read();
    For(kcase,T) {
        ll l,r;
        cin>>l>>r;
        ull ans=f(r)-f(l-1);
        cout<<ans<<endl;
    }   
    return 0;
}

Gym Class

众所周知,度度熊喜欢各类体育活动。
今天,它终于当上了梦寐以求的体育课老师。第一次课上,它发现一个有趣的事情。在上课之前,所有同学要排成一列, 假设最开始每个人有一个唯一的ID,从1到 N ,在排好队之后,每个同学会找出包括自己在内的前方所有同学的最小ID,作为自己评价这堂课的分数。麻烦的是,有一些同学不希望某个(些)同学排在他(她)前面,在满足这个前提的情况下,新晋体育课老师——度度熊,希望最后的排队结果可以使得所有同学的评价分数和最大。
0≤N,M≤100000

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<queue>
#include<vector>
#include<cctype>
#include<ctime>
#include<iomanip> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) 
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (9973)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 

#define MAXN (100000+10)
int n,indegree[MAXN],m;
vi To[MAXN]; 
bool b[MAXN];
priority_queue<int,vi,less<int> > q;
int ans[MAXN],siz;
void topsort()    
{
    siz=0;
    Fork(i,1,n)  
        if (indegree[i]==0)     
        {    
            q.push(i); 
        }    
    while (!q.empty())    
    {    
        int now=q.top(); q.pop();    
        ans[++siz]=now;
        int _si=SI(To[now]) ;
        Rep(i,_si) 
        {    
            int v=To[now][i];
            indegree[v]--;    
            if (indegree[v]==0)    
            {    
                q.push(v); b[v]=1;     
            }                                       
        }       
    }         
    ll c=0;
    Fork(i,2,siz) ans[i]=min(ans[i],ans[i-1]);
    For(i,siz) c+=(ll)ans[i];
    cout<<c<<endl;
}    
int main()
{
// freopen("F.in","r",stdin);
// freopen(".out","w",stdout);
    int T=read();
    For(kcase,T) {
        MEM(indegree) 
        n=read();m=read();
        For(i,m) {
            int a=read(),b=read();
            To[a].pb(b);
            indegree[b]++;
        }   

        topsort();

        For(i,n) To[i].erase(To[i].begin(),To[i].end());
    }   
    return 0;
}

你可能感兴趣的:(2016"百度之星" - 初赛(Astar Round2A)题解)