4610 Cards

模擬題,關鍵是細節


#include<stdio.h>
#include<string.h>
#include<algorithm>
#define LL long long
using namespace std;
const int maxn=1000000+10;
LL ans,q;
int n,k,score[16]={0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4},cou[16],fen[1005];
int sscore[5],nnum[1000],gain[5],wei;
bool vis[5000100];
int pri[maxn],len=0;
bool solve1(int s)
{
    if(vis[s])return 0;
    else  return 1;
}
bool solve2(int s)
{
    if(s==1)return 0;
    int i,j,k,num=1,tmp;
    for(i=0;pri[i]*pri[i]<=s;i++)
    {
        if(s%pri[i]==0)
        {
            tmp=1;
            while(s%pri[i]==0)
            {
                s/=pri[i];
                tmp++;
            }
            //printf("tmp=%d,s=%d,",tmp,s);
            if(s>1||vis[tmp])return 0;
            if(!vis[tmp])return 1;
        }
    }
    return 1;
}
int mypower(int a,int p)
{
    int tmp=a,res=1;
    while(p>0)
    {
        if(p&1)res*=a;
        a=a*a;
        p>>=1;
    }
    res=(res-1)/(tmp-1);
    return res;
}
bool solve3(int s)
{
    int i,j,k,tmp;
    if(s==1)return 0;
    LL sum=0;
    for(i=0;pri[i]*pri[i]<=s;i++)
    {
        if(s%pri[i]==0)
        {
            tmp=1;
            while(s%pri[i]==0)
            {
                tmp++;
                s/=pri[i];
            }
            if(s>1)return 0;
            sum=mypower(pri[i],tmp);
            //printf("sum=%d,",sum);
            if(vis[sum])return 0;
            else return 1;
        }
    }
    if(vis[s+1])return 0;
    return 1;
}
bool solve4(int s)
{
    int i,j,k=0,tmp;
    int sum=1;
    for(i=0;pri[i]*pri[i]<=s;i++)
    {
        if(s%pri[i]==0)
        {
            tmp=0;
            while(s%pri[i]==0)
            {
                tmp++;
                s/=pri[i];
            }
            nnum[k++]=tmp+1;
            sum*=(tmp+1);
            if(s==1)break;
        }
    }
    if(s>1){nnum[k++]=2;sum*=2;}//sum剛開始忘了乘二
    for(i=0;i<k;i++)
    {
        if(nnum[i]%4==0||nnum[i]%4==1)continue;
        if((sum/nnum[i])&1)return 0;
    }
    return 1;
}
void dfs(int s)
{
    if(s==16)
    {
        int regain=0,i,ss=q;
        //printf("q=%d\n",q);
        //printf("wei=%d,",wei);
        if((wei&1)==0)regain+=gain[1];
        if((wei&2)==0)regain+=gain[2];
        if((wei&4)==0)regain+=gain[3];
        if((wei&8)==0)regain+=gain[4];
        q+=regain;
        //printf("wei=%d,q=%I64d\n",wei,q);
        int tmp=k;
        for(i=4;i>=0;i--)
        {
            if(tmp<=sscore[i])
            {
                q+=i*tmp;
                tmp=0;
                break;
            }
            else
            {
                tmp-=sscore[i];
                q+=sscore[i]*i;
            }
        }
        if(tmp==0&&q>ans){
                ans=q;
                //printf("wei=%d,q=%I64d,ans=%I64d\n",wei,q,ans);
        }
        q=ss;//q的值要還原
        return ;
    }
    int i,j;
    dfs(s+1);
    //printf("wei=%d,s=%d,q=%d\n",wei,s,q);
    int h=wei;
    if(cou[s]>0&&k>0)
    {
        wei=wei|s;
        sscore[score[s]]+=cou[s]-1;
        q+=score[s];k--;
        dfs(s+1);
        sscore[score[s]]-=(cou[s]-1);
        wei=h;q-=score[s];k++;
    }
}
int main()
{
    //freopen("1011.in", "r", stdin);
    //freopen("qq.out", "w", stdout);
   int i,j,t,a,tmp,b;
   vis[0]=vis[1]=1;
   for(i=2;i*i<5000000;i++)
      if(!vis[i]){
            for(j=i*i;j<5000000;j+=i)
               vis[j]=1;
      }
   for(i=2;i<5000000;i++)if(!vis[i])
        pri[len++]=i;
        //printf("%d,",pri[len-1]);}
   // while(scanf("%d",&t)!=-1)
    //{
     //   printf("%d\n",solve4(t));
    //}
   scanf("%d",&t);
   while(t--)
   {
         memset(cou,0,sizeof(cou));
         scanf("%d%d",&n,&k);
         for(i=0;i<n;i++)
         {
             scanf("%d%d",&a,&b);
             tmp=0;
             if(solve1(a))tmp+=1;
             if(solve2(a))tmp+=2;
             if(solve3(a))tmp+=4;
             if(solve4(a))tmp+=8;
             cou[tmp]+=b;
             fen[i]=score[tmp];
             //printf("i=%d,fen[i]=%d,tmp=%d\n",i,fen[i],tmp);
         }
         for(i=1;i<=4;i++)scanf("%d",&gain[i]);

         printf("%d",fen[0]);
         for(i=1;i<n;i++)printf(" %d",fen[i]);
         puts("");
         //for(i=0;i<16;i++)printf("%d ",cou[i]);
         //puts("");
         memset(sscore,0,sizeof(sscore));
         ans=-100000000;wei=0;q=0;
         dfs(0);
         printf("%I64d\n",ans);
   }
   return 0;
}


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