2016.10.29 清北學堂NOIP衝刺班Day1 AM 考試總結

成績:滿分300,我得了200,node

1:90//前兩個題目都是模擬,沒用到什麼其餘算法,第一題有可能少考慮了一點細節ios

2:100算法

3:10//感受是個DP,可是毫無思路,只打了個普通揹包,10分而已。spa

題目+數據:http://pan.baidu.com/s/1bpj3SR1code

下面是個人代碼:blog

 

這個題目中我爲了獲得部分分,而特別判斷了幾組數據。排序

T1:get

 1 /*
 2 之後必定要仔細讀數據範圍,必定要。
 3 數據範圍中:20%的數據,只有秒數可能不一樣,言外之意就是可能相同。
 4 而個人程序由於沒有考慮到,時間相同時直接輸出0000,。O__O"…
 5 
 6 一個小技巧:計算時間時,能夠把全部的時間都換算成秒,直接總秒數1-秒數2,不只不會溢出,並且也方便計算。
 7 */
 8 #include<iostream>
 9 using namespace std;
10 #include<cstdio>
11 typedef long long ll;
12 struct Tim{
13     int n,y,r,x,f,m;
14 }tim1,tim2;
15 long long ans=0;
16 int mon[15]={0,31,28,31,30,31,30,31,31,30,31,30,31};
17 bool is_runnian(int x)
18 {
19     if(x%400==0) return true;
20     if(x%100!=0&&x%4==0) return true;
21     return false;
22 } 
23 
24 void input()
25 {
26     scanf("%d-%d-%d %d:%d:%d",&tim1.n,&tim1.y,&tim1.r,&tim1.x,&tim1.f,&tim1.m);
27     scanf("%d-%d-%d %d:%d:%d",&tim2.n,&tim2.y,&tim2.r,&tim2.x,&tim2.f,&tim2.m);
28 }
29 int main()
30 {
31 //    freopen("two.in","r",stdin);
32 //    freopen("two.out","w",stdout);
33     input();
34     if(tim1.n==tim2.n&&tim1.y==tim2.y&&tim1.r==tim2.r)
35     {
36         ans=(ll)(tim2.x*3600+tim2.f*60+tim2.m)-(tim1.x*3600+tim1.f*60+tim1.m);
37     }
38     else  if(tim1.n==tim2.n)
39           {
40               ll d1=0,d2=0;
41               for(int i=1;i<tim1.y;++i)
42                  d1+=mon[i];
43             if(is_runnian(tim1.n)&&tim1.y>2) d1++;
44             for(int i=1;i<tim2.y;++i)
45                d2+=mon[i];
46             if(is_runnian(tim2.n)&&tim2.y>2) d2++;
47             d1+=tim1.r;
48             d2+=tim2.r;
49            ans=(ll)(d2*24*3600+tim2.x*3600+tim2.f*60+tim2.m)-(ll)(d1*24*3600+tim1.x*3600+tim1.f*60+tim1.m);
50               
51           }
52           else{
53               ll d1=0,d2=0;
54               for(int i=2000;i<tim1.n;++i)
55                 if(is_runnian(i)) d1+=366;
56                 else d1+=365;
57               for(int i=2000;i<tim2.n;++i)
58                 if(is_runnian(i)) d2+=366;
59                 else d2+=365;
60               for(int i=1;i<tim1.y;++i)
61                  d1+=mon[i];
62             if(is_runnian(tim1.n)&&tim1.y>2) d1++;
63             for(int i=1;i<tim2.y;++i)
64                d2+=mon[i];
65             if(is_runnian(tim2.n)&&tim2.y>2) d2++;
66             d1+=tim1.r;
67             d2+=tim2.r;
68            ans=(ll)(d2*24*3600+tim2.x*3600+tim2.f*60+tim2.m)-(ll)(d1*24*3600+tim1.x*3600+tim1.f*60+tim1.m);
69           }
70     if(ans) cout<<ans<<"000";
71     else printf("0\n");
72     fclose(stdin);
73     fclose(stdout);
74     return 0;
75 }

 

T2:input

 1 #include<iostream>
 2 using namespace std;
 3 #include<cstdio>
 4 #define N 100010
 5 #define M 50010
 6 #include<algorithm>
 7 #include<queue>
 8 typedef long long ll;
 9 struct node{
10     ll tim;
11     bool operator <(node P)
12     const{return tim>P.tim;}
13 };
14 priority_queue<node>Q;
15 ll ren[N];
16 int n,m;
17 ll read()
18 {
19     ll ret=0;
20     char s=getchar();
21     while(s<'0'||s>'9')
22     {
23         s=getchar();
24     }
25     while(s>='0'&&s<='9')
26     {
27         ret=ret*10+s-'0';
28         s=getchar();
29     }
30     return ret;
31 }
32 void input()
33 {
34     scanf("%d%d",&n,&m);
35     for(int i=1;i<=n;++i)
36       ren[i]=read();
37     for(int i=1;i<=m;++i)
38     {
39         node X;
40         X.tim=ren[i];
41         Q.push(X);
42     }
43 }
44 int main()
45 {
46     freopen("death.in","r",stdin);
47     freopen("death.out","w",stdout);
48     input();
49     for(int i=m+1;i<=n;++i)
50     {
51         node Now=Q.top();
52         Q.pop();
53         Now.tim+=ren[i];
54         Q.push(Now);
55     }
56     printf("%I64d",Q.top());
57     fclose(stdin);
58     fclose(stdout);
59     return 0;
60 }

 T3:string

解析:

看了看題解:感受也是這個道理:也許它並不須要Dp,好比在1*31*2)中,咱們爲了價值最大,確定先放價值大的(由於體積相同嘛),因此咱們就把
價值大的先放進去就能夠了。
這個題目注意兩點便可:

1.有不少體積相同可是價值不一樣的物品,能夠直接用貪心排序,就能夠了。

2.沒必要關注具體的揹包中的物品如何放置,只須要關注能放多少個就能夠了。由於咱們總有辦法使放到幾乎滿了或者滿了的狀況。

因此思路:
能夠直接用n*m/3,n*m/2,計算數目,可是咱們要想想這樣有沒有可能出現錯誤。
n*m/2狀況,若是n*m的揹包1*2這麼放,那麼最後只可能

 

餘下一個空位置,那麼結果是不錯的,可是若是是n*m的狀況,咱們能夠發現,若是知足
n%3==2 && m%3==2 && (n==2 || m==2),若是隻放1*3,最後會餘下一個2*2的正方形不能再放,可是若是直接用n*m/3的話,結果就會多1了。

 

 1 #include<iostream>
 2 using namespace std;
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<cstring>
 6 #define N 10010
 7 int t,n,m,n1,n2,wu1[N],wu2[N];
 8 int sumwu1[N],sumwu2[N];
 9 typedef long long ll;
10 bool cmp1(int a,int b)
11 {
12     return a>b;
13 }
14 int main()
15 {
16 //    freopen("eyesight.in","r",stdin);
17 //    freopen("eyesight.out","w",stdout);
18     scanf("%d",&t);
19     while(t--)
20     {
21         scanf("%d%d%d%d",&n,&m,&n1,&n2);
22         memset(sumwu1,0,sizeof(sumwu1));
23         memset(sumwu2,0,sizeof(sumwu2));
24         for(int i=1;i<=n1;++i)
25           scanf("%d",&wu1[i]);
26         for(int i=1;i<=n2;++i)
27           scanf("%d",&wu2[i]);
28         sort(wu1+1,wu1+n1+1,cmp1);
29         sort(wu2+1,wu2+n2+1,cmp1);
30         for(int i=1;i<=n1;++i)
31           sumwu1[i]=sumwu1[i-1]+wu1[i];
32         for(int i=1;i<=n2;++i)
33           sumwu2[i]=sumwu2[i-1]+wu2[i];
34         ll ans=0;
35         int dalta;
36         if(n%3==2&&m%3==2&&(n==2||m==2)) dalta=4;
37         else dalta=n*m%3;
38         int sum=min(n2,(n*m-dalta)/3);
39         for(int i=0;i<=sum;++i)
40           ans=max(ans,(ll)(sumwu2[i]+sumwu1[min(n1,(n*m-3*i)>>1)]));
41         cout<<ans<<endl;
42         
43     }
44     fclose(stdin);
45     fclose(stdout);
46     return 0;
47 }
相關文章
相關標籤/搜索