2016.10.29 清北学堂NOIP冲刺班Day1 AM 考试总结

时间:2021-07-03 16:43:07

成绩:满分300,我得了200,

1:90//前两个题目都是模拟,没用到什么其他算法,第一题有可能少考虑了一点细节

2:100

3:10//感觉是个DP,但是毫无思路,只打了个普通背包,10分而已。

题目+数据:http://pan.baidu.com/s/1bpj3SR1

下面是我的代码:

 

这个题目中我为了得到部分分,而特别判断了几组数据。

T1:

 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:

 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:

解析:

看了看题解:感觉也是这个道理:也许它并不需要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 }