10.3 聽說這套題很簡單

這裏寫圖片描述
這裏寫圖片描述

T1 叫第二題的第一題

直接算就好。

emmm。。我的方法是把第一個日期往後取整,再把第二個日期往前取整,最後答案加上兩個日期中間的日期差qwq。

代碼

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;

#define ll long long

char s[110];
int Y1=-1,Y2=-1,m1=-1,m2=-1,d1=-1,d2=-1,h1=-1,h2=-1,M1=-1,M2=-1,s1=-1,s2=-1;
int md[14]={0,31,28,31,30,31,30,31,31,30,31,30,31};
ll ans=0;

ll year(int a,int b) // 左閉右開
{
    ll c=0;
    for(int i=a;i<b;++i)
    {
        if(i%4==0&&i%100!=0) c+=366;
        else if(i%400==0) c+=366;
        else c+=365;
    }
    return c*24*60*60*1000;
} 
ll month(int a,int b,int k)
{
    ll c=0;
    for(int i=a;i<b;++i)
    {
        c+=md[i];
        if(i==2&&k) ++c;
    }
    return c*24*60*60*1000;
}
ll day(int a,int b)
{
    ll c=b-a;
    return c*24*60*60*1000;
}
ll hour(int a,int b)
{
    ll c=b-a;
    return c*60*60*1000;
}
ll minute(int a,int b)
{
    ll c=b-a;
    ll k=c*60*1000;
    return k;
}
ll second(int a,int b)
{
    return (b-a)*1000;
}

int main()
{
    freopen("two.in","r",stdin);
    freopen("two.out","w",stdout);
    gets(s);
    int l=strlen(s),num=0;
    for(int i=0;i<=l;++i)
    {
        if(s[i]>='0'&&s[i]<='9') num=num*10+s[i]-'0';
        else{
                if(Y1==-1) Y1=num;
                else if(m1==-1) m1=num;
                else if(d1==-1) d1=num;
                else if(h1==-1) h1=num;
                else if(M1==-1) M1=num;
                else if(s1==-1) s1=num;
                num=0;
        } 
    }
    gets(s);
    l=strlen(s),num=0;
    for(int i=0;i<=l;++i)
    {
        if(s[i]>='0'&&s[i]<='9') num=num*10+s[i]-'0';
        else{
                if(Y2==-1) Y2=num;
                else if(m2==-1) m2=num;
                else if(d2==-1) d2=num;
                else if(h2==-1) h2=num;
                else if(M2==-1) M2=num;
                else if(s2==-1) s2=num;
                num=0;
        } 
    }       
    ll num1=0,num2=0,k1=0,k2=0;
    if(Y1%4==0&&Y1%100!=0) k1=1;
    if(Y1%400==0) k1=1;
    if(Y2%4==0&&Y2%100!=0) k2=1;
    if(Y2%400==0) k2=1;
    if(Y1!=Y2) 
    {
        num1=second(0,s1)+minute(0,M1)+hour(0,h1)+day(1,d1)+month(1,m1,k1);
        num1=year(Y1,Y1+1)-num1;
        num2=second(0,s2)+minute(0,M2)+hour(0,h2)+day(1,d2)+month(1,m2,k2);
        ans=num2+num1+year(Y1+1,Y2);
    }
    else{
            if(m1!=m2)
            {
                num1=second(0,s1)+minute(0,M1)+hour(0,h1)+day(1,d1);
                num1=month(m1,m1+1,k1)-num1;
                num2=second(0,s2)+minute(0,M2)+hour(0,h2)+day(1,d2);
                ans=num1+num2+month(m1+1,m2,k2);
            }
            else{
                     if(d1!=d2)
                     {
                          num1=second(0,s1)+minute(0,M1)+hour(0,h1);
                          num1=day(d1,d1+1)-num1;
                          num2=second(0,s2)+minute(0,M2)+hour(0,h2);
                          ans=num1+num2+day(d1+1,d2);
                     }
                     else{
                             if(h1!=h2)
                             {  
                                  num1=second(0,s1)+minute(0,M1);
                                  num1=hour(h1,h1+1)-num1;
                                  num2=second(0,s2)+minute(0,M2);
                                  ans=num1+num2+hour(h1+1,h2);  
                             }
                             else{
                                      if(M1!=M2)
                                      {
                                           num1=second(0,s1);
                                           num1=minute(M1,M1+1)-num1;
                                           num2=second(0,s2);
                                           ans=num1+num2+minute(M1+1,M2);
                                      }
                                      else{
                                              if(s1!=s2){
                                                   ans=second(s1,s2);
                                              }
                                      } 
                             }
                    }
            }
    }
    printf("%lld",ans);
    return 0;
}

這裏寫圖片描述

T2 你做過接水問題嗎?

請百度 codevs 接水問題。

貪心,每次從堆中彈出當前打sif總時間最小的那個位置,加上當前人所用的時間再扔進去。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
#define ll long long

int M,N;
int time[100010]; 

priority_queue<ll,vector<ll>,greater<ll> > q;

int main()
{
    freopen("death.in","r",stdin);
    freopen("death.out","w",stdout);
    scanf("%d%d",&N,&M);
    for(int i=1;i<=N;++i)
    {
        scanf("%d",&time[i]);
        if(i<=M) q.push(time[i]);
    }
    if(M>N) 
    {
        printf("%d",0);
        return 0;
    }
    for(int i=M+1;i<=N;++i)
    {
        ll a=q.top();
        q.pop();
        a+=time[i];
        q.push(a); 
    }
    ll a=q.top();
    printf("%lld",a);
    return 0;
}

這裏寫圖片描述

T3 出題人想要的不是dp

首先,這並不是一個dp題,而是一個貪心題。(dp會T)

首先說一下dp。

可以打一個裸的01揹包問題。因爲只有1 * 3和1 * 2的物品,所以在數量都夠的前提下,我們是可以一直往裏塞直到揹包全部填滿或是只剩下一個空爲止。數量不夠的話也可以一直往裏填。貌似是正確的。

雖然這道題dp可以水到60分,但是其實是有反例的。(不知道爲什麼沒有被卡)

如:

1
2 5 0 3
3 4 5

dp輸出12,但答案其實是9,因爲畫出來後是這樣:

這裏寫圖片描述

其實這個黃的是沒法放進去的,也就是說,如果N或M爲2,而另一個%3==2,同時1*2的塊又不夠的時候,dp是會被卡掉的。

正解 前綴和+枚舉

因爲數據範圍太大 、同時物品的體積只有1 * 2和1 * 3兩種情況,考慮枚舉更新。

採用前綴和進行優化。先對物品按照價值從大到小排序,再計算可以放入體積爲3

的物品的最大數量(因爲3很特殊)。注意特判剩餘體積爲4但是不能放3的情況(也就是上面的反例)。

另外還要注意到所放的最大物品數不能超過你所擁有的物品數。

代碼

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

int N,M,T,n1,n2;
int w1[100010],w2[100010],sum1[100010],sum2[100010];

bool cmp(int a,int b){ return a>b ; }

int main()
{
     freopen("eyesight.in","r",stdin);
     freopen("eyesight.out","w",stdout);
     scanf("%d",&T);
     while(T--)
     {
         scanf("%d%d%d%d",&N,&M,&n1,&n2);
         for(int i=1;i<=n1;++i)
             scanf("%d",&w1[i]);
         for(int i=1;i<=n2;++i)
             scanf("%d",&w2[i]);
         sort(w1+1,w1+n1+1,cmp);
         sort(w2+1,w2+n2+1,cmp);
         for(int i=1;i<=n1;++i) sum1[i]=sum1[i-1]+w1[i];
         for(int i=1;i<=n2;++i) sum2[i]=sum2[i-1]+w2[i];
         int size=N*M,maxn2,maxn3,ans=-1;
         if((N==2&&M%3==2)||(M==2&&N%3==2)) maxn3=(size-4)/3;
         else maxn3=size/3;
         maxn3=min(maxn3,n2);
         for(int i=0;i<=maxn3;++i)
         {
              maxn2=min((size-3*i)/2,n1);
              ans=max(ans,sum1[maxn2]+sum2[i]);
         }
         printf("%d\n",ans);
     }
     return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章