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 }
时间: 2024-10-25 23:35:22

2016.10.29 清北学堂NOIP冲刺班Day1 AM 考试总结的相关文章

洛谷P1080 [NOIP2012提高组D1T2]国王游戏 [2017年5月计划 清北学堂51精英班Day1]

P1080 国王游戏 题目描述 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右 手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排 成一排,国王站在队伍的最前面.排好队后,所有的大臣都会获得国王奖赏的若干金币,每 位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右 手上的数,然后向下取整得到的结果. 国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序, 使得获得奖赏最多的大

P2327 [SCOI2005]扫雷 [2017年5月计划 清北学堂51精英班Day1]

P2327 [SCOI2005]扫雷 题目描述 输入输出格式 输入格式: 第一行为N,第二行有N个数,依次为第二列的格子中的数.(1<= N <= 10000) 输出格式: 一个数,即第一列中雷的摆放方案数. 输入输出样例 输入样例#1: 2 1 1 输出样例#1: 2 其实还是扫雷玩的少..知道思路之后很快 只需枚举前两个各自的情况,后面的各自便能够计算出来 注意几个细节(在代码里面) #include <iostream> #include <cstdio> #in

【模板】 递归线段树 [2017年五月计划 清北学堂51精英班Day4]

P3372 [模板]线段树 1 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含3或4个整数,表示一个操作,具体如下: 操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k 操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的

【模板】倍增LCA [2017年5月计划 清北学堂51精英班 Day3]

P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每行包含两个正整数x.y,表示x结点和y结点之间有一条直接连接的边(数据保证可以构成树). 接下来M行每行包含两个正整数a.b,表示询问a结点和b结点的最近公共祖先. 输出格式: 输出包含M行,每行包含一个正整数,依次为每一个询问的结果. 输入输出样例 输入

2017 国庆清北刷题冲刺班《角谷猜想》

原创建时间:2018-07-04 20:05:44 不错的字符串模拟 题目描述 某个名字末尾是654321的小A同学是个大家眼中公认的学霸(虽然他永远不承认),他对题目的直觉到了一种可怕的地步,一眼看出题目的算法对他而言只是小 Case,他甚至能在看到一个证明的瞬间敏锐地判断出这个证明的真伪. 现在小A同学机缘巧合地看到了角古猜想(即对于\(x\)当它为奇数则\(x=3x+1\),\(x\)为偶数,则\(x=\frac{x}{2}\),一直重复这个步骤,则最终\(x\)会变为\(1\)),在看完

铁轨 清北学堂 线段树

铁轨 清北学堂 线段树 [题目描述] R 国的铁轨经常会进行重新修建. R 国是一个细长的国家,一共有 n 个城市排成一排,首都位于 1 号城市,相邻两个城市之间有铁路相连. 每次新建铁轨的时候,一定是从首都开始修建,直到某一个城市为止,这其间的铁路都会变成新版本的设 施,而旧设施会被拆除.然而,由于 R 国的工程师脑子不太好使,任意两种不同版本的铁路之间都无法连 接,因此必须要进行换乘. 现在给出你修建铁轨的操作,小 R 时不时第会想问你,如果在第 x 个城市到第 y 个城市之间随机选择一个

清北学堂2017NOIP冬令营入学测试 P4744 A’s problem(a)

清北学堂2017NOIP冬令营入学测试 P4744 A's problem(a) 时间: 1000ms / 空间: 655360KiB / Java类名: Main 背景 冬令营入学测试题,每三天结算一次成绩.参与享优惠 描述 这是一道有背景的题目,小A也是一个有故事的人.但可惜的是这里纸张太小,小A无法把故事详细地说给大家听.可能小A自己也讲不清楚自己的故事,因为如果讲清了,也就没有这道题目了-- 小A的问题是这个样子,它找到了n份不同的工作,第i份工作每个月有ai的工资,每份工作需要小A每天

2016.10.29 NOIP模拟赛 PM 考试整理

300分的题,只得了第三题的100分. 题目+数据:链接:http://pan.baidu.com/s/1o7P4YXs 密码:4how T1:这道题真的是跪在游戏玩少了. 我忽视了游戏中的两个常识:1.开始的序列是无法消除的(这与题目描述明显不符啊),即使有很多可以连消的,而我的程序每次只在插入的位置向两侧寻找可以消除的,自然就错了. 2.开始时的序列居然可以为空,真是让人措手不及! 正确做法:用指针链表,而且不可以用数组模拟.

2017.7.21夏令营清北学堂解题报告

预计分数: 60+30+0=90=划水 实际分数: 90+30+20=140=rank5=雷蛇鼠标 一句话总结:今天该买彩票! T1: 题目描述 从前有一个?行?列的网格. 现在有?种颜色,第?种颜色可以涂??格,保证 Σ? ?? = ? * ?. 需要你对这个网格图进行着色,你必须按照从上到下,每一行内从左到右 的顺序进行着色,并且在用完一种颜色前你不能换颜色(当然颜色的使用顺序 是随意的). 每个相邻的相同色块可以获得1分,问在给定的规则下进行着色所能获得的 最高分是多少. 多组数据. 输入