【SSOJ 4192 做题方案】题解
题目链接
题目
为了期末考取得好成绩,同学们都加倍努力进行复习。
为了考得比其他同学好,小泽决定每一科都认真地多做1道题目,以提高对知识点的理解和熟悉程度!
已知期末要考4门课,分别是《C++编程》、《算法入门》、《数据结构》、《搜索算法》,每一门课老师都准备了n道复习题,第一道题的耗时分别是\(a_1、b_1、c_1、d_1\),第二道题的耗时分别是\(a_2、b_2、c_2、d_2\)……
小泽打算花恰好m分钟(充分利用时间)来完成4道题,每个科目各一道,请问有多少种选择方案?
思路
先对 \(a\) 与 \(b\) 的和作个排序,再对 \(c\) 与 \(d\) 的和作个排序,然后双指针跑一遍统计答案。
总结
这道题我一开始想的是把两个和做出来后作个二分,后来发现答案符合单调性,双指针即可。
对于要对数列多次二分的题目,一般都可以用双指针优化。
Code
#include<bits/stdc++.h>
using namespace std;
#define int long long
inline 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<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
//#define M
//#define mo
#define N 510
int n, m, i, j, k;
int a[N], b[N], c[N], d[N], x[N*N], y[N*N];
int l, r, ans;
signed main()
{
// freopen("tiaoshi.in", "r", stdin);
// freopen("tiaoshi.out", "w", stdout);
n=read(); m=read();
for(i=1; i<=n; ++i) scanf("%lld%lld%lld%lld", &a[i], &b[i], &c[i], &d[i]);
for(i=1; i<=n; ++i) for(j=1; j<=n; ++j) x[(i-1)*n+j]=a[i]+b[j];
for(i=1; i<=n; ++i) for(j=1; j<=n; ++j) y[(i-1)*n+j]=c[i]+d[j];
sort(x+1, x+n*n+1);
sort(y+1, y+n*n+1);
for(l=1, r=n*n; l<=n*n; ++l)
{
while(r&&x[l]+y[r]>m) --r;
ans+=r;
}
printf("%lld\n", ans);
return 0;
}
本文来自博客园,作者:zhangtingxi,转载请注明原文链接:https://www.cnblogs.com/zhangtingxi/p/15795333.html