第二题
【题目描述】
给你两个日期,问这两个日期差了多少毫秒。
【输入格式】
两行,每行一个日期,日期格式保证为“YYYY-MM-DD hh:mm:ss ”这种形式。第二个日期时间一定比第一个日期时间要大两个日期的年份一定都是 21 世纪的年份。
【输出格式】
一行一个整数代表毫秒数。
【样例输入 1】
2000-01-01 00:00:00
2000-01-01 00:00:01
【样例输出 1】
1000
【样例输入 2】
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
2000-01-01 00:00:00
2000-11-11 00:00:00
【样例输出 2】
27216000000
【样例解释】
从前有座山。
天,这道题真是太恶心了!!!!这是我做过最恶心的暴力!!(没有之一!)
唉,做了半天还是没A。。。。(烦气,╭(╯^╰)╮)
气死我了。。。多加了一个零,然后找了1个小时才找出来的。。。。。
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define rn 31622400LL//一闰年的秒数 #define pn 31536000LL//一平年的秒数 using namespace std; long long ans;//一年365*24*60=525600分 525600*60=31536000秒 31536000*1000毫秒 暴不了long long int n[3],y[3],r[3],h[3],m[3],s[3];//这样方便很多 int d1[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};//闰年二月29天,平年28天 int d2[13]={0,31,29,31,30,31,30,31,31,30,31,30,31}; int judge(int x)//判断是否为闰年。判断闰年一般的规律为: 四年一闰,百年不闰,四百年再闰. { if(x%100==0) { if(x%400==0) return true; return false; } else if(x%4==0) return true; return false; } int run(int x) { long long q=0; if(judge(n[x])) for(int i=1;i<y[x];i++) q+=d2[i]*86400; else for(int i=1;i<y[x];i++) q+=d1[i]*86400; q+=(r[x]-1)*86400+h[x]*3600+m[x]*60+s[x]; return q; } int main() { freopen("two.in","r",stdin); freopen("two.out","w",stdout); scanf("%d-%d-%d %d:%d:%d",&n[1],&y[1],&r[1],&h[1],&m[1],&s[1]); scanf("%d-%d-%d %d:%d:%d",&n[2],&y[2],&r[2],&h[2],&m[2],&s[2]); for(int i=n[1]+1;i<n[2];i++)// 计算他们两中间间隔的年,当年由于月份不全就不直接加一年内的秒数了。。 if(judge(i)) ans+=rn;// 至于为什么要从n[1]开始,我们这样考虑,我们后面由于方便把它合并到一个函数中了,但是第一年与第二难相差的月份为第二年过去的月份+第一年剩下的月份 else ans+=pn;//但是在函数中我们都写的是过去的月份,但是这样总月份-过去的月份不就等于剩下的月份吗?! if(judge(n[1])) ans+=rn;else ans+=pn; ans+=run(2);ans-=run(1); if(n[1]==n[2]) if(judge(n[1])) ans-=rn;else ans-=pn; if(ans==0) printf("0\n"); else printf("%I64d000",ans); return 0; }
死亡(唉,这么简单的暴力当时我竟然没A。。。。。。。╭(╯^╰)╮)
【问题描述】
现在有?个位置可以打 sif,有? +1个人在排队等着打 sif。现在告诉你 个人每个人需要多长的时间打 sif,问你第? +1个人什么时候才能打 sif。 (前?
个人必须按照顺序来)
【输入格式】
第一行两个整数?,?如上所述。
接下来?行每行一个整数代表每个人所需要用的时间。
【输出格式】
一行一个整数表示答案。
【样例输入】
3 2
1
1
1
【样例输出】
1
【样例解释】
山里有座庙。
【数据规模与约定】
对于100%的数据,每个人所需用的时间不超过10 5 。
测试点 ? ? 测试点 ? ?
1 10 10 1 5000 500
2 20 10 2 100000 5000
3 50 10 3 100000 10000
4 1000 500 4 100000 20000
5 2000 500 5 100000 50000
代码:
#include<queue> #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define N 100001 using namespace std; priority_queue<int,vector<int>,greater<int> >q; int n,m,a[N],mx; int read() { int x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘) f=-1; ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘; ch=getchar();} return x*f; } int main() { freopen("death.in","r",stdin); freopen("death.out","w",stdout); n=read(),m=read(); for(int i=1;i<=n;i++) a[i]=read(); for(int i=1;i<=m;i++) q.push(0);//最开始时需要等的时间为0 for(int i=1;i<=n+1;i++) { mx=q.top(); q.pop(); q.push(mx+a[i]);//这样我们就一次求出了每个人节水是需要等的时间,为什么需要小根堆取最小?你排队打水的时候,你肯定去排的时间最短的时间的地方去打水啊。除非你吃饱了撑的 if(i==n+1) { printf("%d",mx); return 0; } } }
凝视
【问题描述】
背包是个好东西,希望我也有。
给你一个二维的背包,它的体积是? × ?。现在你有一些大小为1× 2和1×
3的物品,每个物品有自己的价值。你希望往背包里面装一些物品,使得它们的
价值和最大,问最大的价值和是多少。
【输入格式】
第一行一个整数?代表该测试点的数据组数。
对于每组数据,第一行有四个整数?,?,? 1 ,? 2 ,其中? 1 ,? 2 分别代表大小为
1× 2和大小为1 × 3的物品个数。
1 × 2 接下来一行有? 2 个数代表每个1 × 3物品的价值。
【输出格式】
对于每组询问,输出能够达到的价值最大值。
【样例输入】
1
2 3 2 2
1 2
1 2
【样例输出】
4
【样例解释】
庙里有座山。
【数据规模与约定】
2,? 1 ,? 2 ≤ 100。
70%的数据,?,? ≤ 100,? 1 ,? 2 ≤ 2000。
对于100%的数据,1 ≤ ? ≤ 10,1 ≤ ?,? ≤ 500,0 ≤ ? 1 ,? 2 ≤ 10000。
一看到这个题想到的莫过于二维背包了,然后我就屁颠屁颠的敲了个二维背包交了上去(然后。。。。爆零。。。。)
唉,正解是一个基于连通性的状压dp(显然,我不会。。。)
学长博客里有。。http://www.cnblogs.com/yanlifneg/p/6011579.html
那这个题我们就来看一个简单点的做法吧。。。(枚举)
我们可以看出我们只有两种选择,要么是1*3要么是1*2,那这样的话,我们若用若干个1*3的物品填充背包,那么剩下的空间一定使用1*2的物品来填充,那么,我们暴力枚举出需要用多少1*3的物品,这样我们所需的1*2的物品就可以用O(1)来算出来。
但是你有没有想到有一种特殊情况:如果一个背包的体积为4(2*2),这样的话,是不是就不能用1*3的物品来填充这个背包?!
以此类推,,当n=2,m%3=2时,铺到最后都会出现这种情况。。(这也就是背包为什么不对的原因。)
代码:
#include<cstdio>
#include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define N 100010 using namespace std; int t,n,m,n1,m1,a1[N],a2[N],s1[N],s2[N],ans; int cmp(int x,int y) { return x>y; } int read() { int x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘) f=-1; ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘; ch=getchar();} return x*f; } int main() { t=read(); while(t--) { memset(s1,0,sizeof(s1)); memset(s2,0,sizeof(s2)); n=read(),m=read(),n1=read(),m1=read(); if(n>m) swap(n,m); for(int i=1;i<=n1;i++) a1[i]=read(); for(int i=1;i<=m1;i++) a2[i]=read(); sort(a1+1,a1+1+n1,cmp); sort(a2+1,a2+1+m1,cmp);//我们用的时候肯定是先用体积相同但是价值高的的了。。 for(int i=1;i<=n1;i++) s1[i]=s1[i-1]+a1[i];//其实这两个地方可以不这样写的 ,但是这样比较方便 for(int i=1;i<=m1;i++) s2[i]=s2[i-1]+a2[i];//我们处理出选取几个当前个数的物品的价值,在后面就可以直接用了。 ans=0; int j; for(int i=0;i<=m1;i++)//枚举放的1*3的物品的个数 { if(i*3>n*m) break;//放不下了。。。 j=(n*m-i*3)>>1;//能放得1*2物品的个数 ans=max(ans,s1[j]+s2[i]);//我们一定是让放进去的价值最大 if(j>n1) ans=max(ans,s2[i]+s1[n1]);//为什么?? 我们总共就有n1个1*2的物品,你还能多生出来几个啊。。。 if(n==2&&m%3==2&&j==2) break;//这就是我们特殊判断的情况 n=2&&m%2=2&&j==2这种情况是我们恰能弄出2*2的 这种情况, //并且我们当前所出的情况恰又刚好是剩下的体积为2*2的情况,这是我们是一定不能再放1*3的物品了的了。 } printf("%d\n",ans); } return 0; }