2016.10.29 清北学堂NOIP冲刺班Day1 AM 考试总结
Posted tech-chen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2016.10.29 清北学堂NOIP冲刺班Day1 AM 考试总结相关的知识,希望对你有一定的参考价值。
成绩:满分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*3(1*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 }
以上是关于2016.10.29 清北学堂NOIP冲刺班Day1 AM 考试总结的主要内容,如果未能解决你的问题,请参考以下文章
清北·NOIP2017济南考前冲刺班 DAY1 morning