Codeforces #355 div.2

B.

題意:輸入n,h,k,分別表示n個土豆,規定能放入壓土豆機的最大高度,k表示每次壓土豆機壓碎土豆的高度。問機器最少需要壓幾次?

思路:我直接想到的這就是一個模擬的過程,trick點就是n是1e5,h是1e9,所以壓的次數會爆int.

被×了 23333.

#include<bits/stdc++.h>
using namespace std;
int a[100005];
int main()
{
    int n,h,k,now=0;
    long long t=0;
    scanf("%d%d%d",&n,&h,&k);
    for(int i=0; i<n; i++)
        scanf("%d",&a[i]);
    for(int i=0; i<n-1; i++)
    {
        //將每次循環到的a[i]視爲目前壓土豆機裏的土豆高度.
        if(!a[i])continue;  //這裏其實也可有可無。
        if(a[i]+a[i+1]>h)
        {
            while(a[i]+a[i+1]>h)     //最多循環兩次。(a[i]/k得到的餘數必定小於k)
            {
                if(a[i]<k)
                {
                    t++;
                    a[i]=0;
                }
                t+=a[i]/k;             //如果加上a[i+1]>h,那麼就先對a[i]進行處理。
                a[i]=a[i]%k;
                if(!a[i])break;  //因爲a[i]<=h,所以可有可無
            }
        }
        if(a[i]+a[i+1]<=h)
        {
            t+=(a[i]+a[i+1])/k;
            a[i+1]=(a[i]+a[i+1])%k;       //如果有剩餘的土豆高度不足k,那麼就轉移到下一次進行壓碎。
        }
    }
    if(a[n-1]%k)
        t+=a[n-1]/k+1;
    else t+=a[n-1]/k;
    printf("%lld\n",t);
}


上面自己寫的代碼太繁瑣。

下面是簡潔的,

#include<bits/stdc++.h>
int main()
{
    int n,h,k,h1,now=0; //now表示目前處理器內土豆累積的高度。
    long long ans=0;
    scanf("%d%d%d",&n,&h,&k);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&h1);
        if(now+h1>h) //目前土豆累積的高度加上將要放入的土豆高度如果超過h,那麼之前土豆累積的高度必須先清0;
        {
            ans++;
            now=0;
        }
        now+=h1;
        ans+=now/k;
        now=now%k;
    }
    if(now)  //now是必定小於k的.
        ans++;
    printf("%lld\n",ans);
}


C.

題意:給一個字符串s,求某兩個與s相同長度的字符串進行&運算後,可以得到字符串s。0-9,A-Z,a-z,-,_分別表示從0-63的64進制。

思路:先考慮一個字母的時候,那麼如果兩個字母進行&運算後要得到該字母,因爲是64進制,所以O(64^2)的複雜度預處理一下,那麼長度|s|的s字符串只要逐位相乘%mod.

還有一種做法就是觀察&運算,因爲&運算的結果是隻有4種的(0&1=0,0&0=0,1&0=0,1&1=1),所以對於一個字母的64進制,例如樣例一,Z的64進製爲35,二進制爲(100011),那麼每位能夠得到0的可能爲3種,

那麼只要數每一個字母二進制低6位的0的個數num,因爲最大的數字63是低6位的,每個字母的可能性就是3^num。

第一種做法:

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int t[200],pre[200];
char s[100005];
int main()
{
   memset(t,0,sizeof(t));
   memset(pre,0,sizeof(pre));
   for(int i=0;i<10;i++)
    t['0'+i]=i;
   for(int i=0;i<26;i++)
   {t['a'+i]=36+i;
    t['A'+i]=10+i;
   }
   t['-']=62;
   t['_']=63;
   for(int i=0;i<64;i++)
    for(int j=0;j<64;j++)
    pre[i&j]++;

   scanf("%s",s);
   long long  ans=1;
   for(int i=0;i<strlen(s);i++)
    ans=ans*pre[t[s[i]]]%mod;
    printf("%lld\n",ans);
}


第二種做法:

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int t[200],pre[200];
char s[100005];
int main()
{
    memset(t,0,sizeof(t));
   memset(pre,0,sizeof(pre));
   for(int i=0;i<10;i++)
    t['0'+i]=i;
   for(int i=0;i<26;i++)
   {t['a'+i]=36+i;
    t['A'+i]=10+i;
   }
   t['-']=62;
   t['_']=63;
   scanf("%s",s);
   long long ans=1;
   for(int i=0;i<strlen(s);i++)
   {
       int now=t[s[i]];
       for(int j=0;j<6;j++)
           if(!((now>>j)&1))
        ans=ans*3%mod;
   }
   printf("%lld\n",ans);
}



















































在Codeforces上熬夜打的第二場比賽,一直處於減分狀態,漲分的日子什麼時候才能到阿~~~

永遠都不要給自己找藉口!,自己的不滿說到底都是自己的不足造成的,還是刷題,補題吧~~



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