[The 14th Zhejiang University Programming Contest]

題目鏈接:

http://acm.zju.edu.cn/onlinejudge/showContestProblems.do?contestId=354


A.   zoj 3767 Elevator

題目意思:

判斷n個人的重量是否超過電梯的總載重量。

解題思路:

水題

代碼:

//#include<CSpreadSheet.h>

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#include<cmath>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

int main()
{
   //freopen("in.txt","r",stdin);
   //freopen("out.txt","w",stdout);

   int t,n,m;

   scanf("%d",&t);
   while(t--)
   {
       scanf("%d%d",&n,&m);
       int res=0;

       for(int i=1;i<=n;i++)
       {
           int a;
           scanf("%d",&a);
           res+=a;
       }
       if(res>m)
        printf("Warning\n");
       else
            printf("Safe\n");
   }
   return 0;
}



B.  zoj 3668 Continuous Login

迭代加深搜索,因爲總分組數很少,深度不會很大。

解題報告:http://blog.csdn.net/cc_again/article/details/25566503


C.  zoj 3769 Diablo III

將限制條件轉化去掉後轉化成揹包問題,要注意常數優化,排個序&把第一個單獨拿出來考慮。

解題報告:http://blog.csdn.net/cc_again/article/details/25984915


D.  zoj 3770 Ranking System

題目意思:

有n個人,每個人有一個ID、分數和進公司日期,要把這n個人分成6個等級。

分法:分數爲0的人等級爲1,達不到等級爲3或者更高的人等級爲2,分越高者等級越高,分數一樣者先進公司者等級高,如果還一樣誰的ID小者等級高。

告訴每個等級的人數,輸出每個人所在的等級。

解題思路:

模擬

先把人按分數高+進公司日期早+ID號小的優先順序排序,然後從等級高的開始往下分配,直到每個等級的人都分配完了。注意等級1的人得0分,是固定不變的。

代碼:

//#include<CSpreadSheet.h>

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#include<cmath>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

#define Maxn 2200

struct PP
{
    int yy,mm,dd,id,s;
    int pos,le;

}pp[Maxn];
int ans[Maxn],num[10],n,zh;

bool cmp(PP a,PP b)
{
    if(a.s!=b.s)
        return a.s>b.s;
    if(a.yy>b.yy)
        return false;
    else if(a.yy<b.yy)
        return true;
    if(a.mm>b.mm)
        return false;
    else if(a.mm<b.mm)
        return true;

    if(a.dd>b.dd)
        return false;
    else if(a.dd<b.dd)
        return true;

    return a.id<b.id;

}

int main()
{
   //freopen("in.txt","r",stdin);
   //freopen("out.txt","w",stdout);

   int t;

   scanf("%d",&t);
   while(t--)
   {
       zh=0;
       scanf("%d",&n);
       for(int i=1;i<=n;i++)
       {
           scanf("%d%d/%d/%d%d",&pp[i].id,&pp[i].yy,&pp[i].mm,&pp[i].dd,&pp[i].s);
           //printf(":%d %d %d\n",pp[i].yy,pp[i].mm,pp[i].dd);
           if(pp[i].s>0)
                zh++;
           pp[i].pos=i;
       }
       num[6]=(int)floor(zh*0.03); //計算每個等級的人數
       num[5]=(int)floor(zh*0.07);
       num[4]=(int)floor(zh*0.2);
       num[3]=(int)floor(zh*0.3);

       sort(pp+1,pp+n+1,cmp);
       /*for(int i=1;i<=n;i++)
            printf(":%d\n",pp[i].pos);*/
       int tt=1;

       for(int i=6;i>=3;i--)
       {
           for(int j=tt;j<(tt+num[i]);j++)
               ans[pp[j].pos]=i;
           tt=tt+num[i];
       }
       for(int i=tt;i<=n;i++)
       {
           if(pp[i].s)
               ans[pp[i].pos]=2;
           else
                ans[pp[i].pos]=1;
       }

       for(int i=1;i<=n;i++)
            printf("LV%d\n",ans[i]);

   }
   return 0;
}




F.  zoj  3772 Calculate the Function

線段樹維護區間的矩陣乘積後的矩陣,注意矩陣乘法的順序。

解題報告:http://blog.csdn.net/cc_again/article/details/26093941


H.  zoj 3773 Power of Fibonacci

題目意思:

求F1^k+F2^k+...+Fn^k

n<=10^18 k<=100000  Fn爲斐波拉契數列的第n項

解題思路:

數論、逆元、二次剩餘。終於知道帶根號的數模上一個數怎麼處理了。 

Tips:要求局部的x^(1/y) mod p 的話只要滿足x是p的y次剩餘,就可以由滿足剩餘的那個數代替運算

參考這位大神思路:http://blog.csdn.net/acdreamers/article/details/23039571

代碼:

//#include<CSpreadSheet.h>

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#include<cmath>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000009
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

#define Maxn 110000
LL cc[Maxn],aa[Maxn],bb[Maxn];
LL n,k;

void init()
{
    cc[0]=1;
    for(LL i=1;i<=100000;i++) //階乘
        cc[i]=cc[i-1]*i%M;
    aa[0]=bb[0]=1;
    for(LL i=1;i<=100000;i++) // a=(sqrt(5)+1)/2  b=(sqrt(5)-1)/2 用一個整數代替
    {
        aa[i]=aa[i-1]*691504013%M;
        bb[i]=bb[i-1]*308495997%M;
    }
}

LL quick(LL a,LL b)
{
    LL res=1;

    while(b)
    {
        if(b&1)
            res=res*a%M;
        b>>=1;
        a=a*a%M;
    }
    return res;
}

int main()
{
   //freopen("in.txt","r",stdin);
   //freopen("out.txt","w",stdout);

   /*for(LL i=7000000;;i++)   5是1000000009的二次剩餘 x^2=5%1000000009 x的一個解爲383008016
   {
       if(i*i%M==5)
       {
           printf("%lld\n",i);
           break;
       }
   }*/
   init();
   int T;

   scanf("%d",&T);
   while(T--)
   {
       scanf("%lld%lld",&n,&k);
       LL ans=0;

       for(int r=0;r<=k;r++) //枚舉C(k,r)
       {
           LL x=aa[k-r]*bb[r]%M; //a^(k-r)*b(r)
           LL y=cc[k]; //k!
           LL y1=cc[r],y2=cc[k-r];
           y=cc[k]*quick(y1,M-2)%M*quick(y2,M-2)%M; //C(k,r)  k!/(r!*(k-r)!)


           LL temp=x*(quick(x,n)-1)%M*quick(x-1,M-2)%M; //等比數列求和 t*(t^n-1)/(t-1)
           if(x==1) //當公比爲1時不能按照這個來求 都爲1 相加得n
                temp=n%M;
           temp=temp*y%M; //乘上C(k,r)
           if(r&1)
                ans=((ans-temp)%M+M)%M;
           else
                ans=(ans+temp)%M;
       }
       LL temp=quick(383008016,M-2); //最後還有個(1/sqrt(5))^k次方 先求出逆元

       ans=ans*quick(temp,k)%M; //相乘即可得出結果
       printf("%lld\n",ans);

   }
   return 0;
}
/*
383008016

*/


I.  zoj 3775 ?(>_0)!

題目意思:

給一種語言,告訴規則,讓你判斷這種語言輸出的結果和源代碼是否一樣。

解題思路:

實際上只用判斷’_'和‘!'的個數就可以解決問題了。

’_'最多隻能有一個,因爲它的意思是把源代碼按原型輸出一遍,如果存在‘!'那麼原文一定是“hello, world!hello, world!..."且出現的次數和‘!'出現的次數應該一樣。

注意考慮空串的情況。

代碼:

//#include<CSpreadSheet.h>

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#include<cmath>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

#define Maxn 440

char save[Maxn];

char ba[]={"Hello, world!"};

int main()
{
   //freopen("in.txt","r",stdin);
   //freopen("out.txt","w",stdout);
   int t;

   scanf("%d",&t);
   getchar();

   while(t--)
   {
       gets(save);

       int len=strlen(save),ans0=0,ans1=0;

       for(int i=0;i<len;i++)
       {
           if(save[i]=='_')
                ans0++;
           else if(save[i]=='!')
                ans1++;
       }
       if(ans0>1) //'_'超過1個肯定不行
       {
           printf("No\n");
           continue;
       }
       if(ans0==1) //恰好爲1個
       {
           if(ans1) //如果存在'!'也不行
           {
               printf("No\n");
           }
           else
                printf("Yes\n");
          continue;
       }
       if(ans1==0)  //沒有'_' 且沒有'!'
       {
           if(!len) //如果是空串 這種情況沒考慮的話會wa
                printf("Yes\n");
           else      //否則不行
                printf("No\n");
           continue;
       }

       bool flag=true;  //判斷'!'的個數是否和“hello, world!"出現的個數一樣
       int i=0,j=0;

       while(i<ans1&&j<len)
       {
           if(strncmp(save+j,ba,13)!=0)
           {
               flag=false;
               break;
           }
           i++;
           j+=13;
       }
       if(i!=ans1||j!=len)
            flag=false;
       if(!flag)
            printf("No\n");
       else
            printf("Yes\n");



   }
   return 0;
}




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