预计得分 50+0+60 + 100+100+0
实际得分 40+0+30 + 100+40
DAY 2 morning
T1
暴力做法:
30:搜索
20:从小到大排序一个一个加
20:枚举从那栋楼开始跳
马姐做法:
高度从低往高排序
枚举最矮的楼和最高的楼
然后确定中间跳那些楼
然后将中间的跳楼准备代价从小到大加起来
(O(n^3 log(n)))
标程:
同样从低往高排序
动态规划
(f[i][j])跳到i已经跳了j栋楼的最小花费
(f_ij=min(〖f_k〗_(j−1 ) )+c_k+|h_k−h_i)|
(O(n^3))
T2 city
将两个序列排序
则a_1+a_2=b_1
a_1+a_3=b_2
但是无法确定a_2+a_3
因为无法确定a_2+a_3和a_1+a_4 的大小关系
只需确定出a_2+a_3就可以求解出a_1,a_2,a_3
然后根据a_1,a_2,a_3求解出所有数
确定a_2+a_3只需枚举他为b中的数
验证所有解即可
T3 light
数据结构
链表
分块
p≤〖10〗^4
枚举一个p
建立一个0−p−1的数组之类的东西
所以不能对所有的p预处理
所以分开来做
1.可以对1≤p≤100的进行预处理
2.查询v,v+p,v+2p+⋯⋯+v+kp在序列中的上下标位置
失分原因
上午是因为暴力写炸了
第三题30分部分分直接写错了
其实是很好拿的
下午是因为二分范围出错了
233
一共有79498个质数
所以需要(l=k,r=78498),我写的是(r=9592)
天知道我怎么算出这个9592的……233
还有一个地方是把(10^6)少写了一个(0)
我的40分应该也有他的一份贡献
好像改了后者这个错误就70分了
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int sum;
long long ans;
bool isP[10000005];
int Prime[10000005];
long long P[10000005];
void read(int &s){
char ch=getchar();
for(;!isdigit(ch);ch=getchar());
for(s=0;isdigit(ch);s=s*10+ch-'0',ch=getchar());
}
bool can(int mid,int k,int n){
long long number=P[mid]-P[mid-k];
if(number<=(long long)n){
ans=number;
return true;
}
else return false;
}
int main(){
freopen("diary.in","r",stdin);
freopen("diary.out","w",stdout);
memset(isP,1,sizeof(isP));
isP[0]=isP[1]=0;
for(int i=2;i<=10100;++i)
if(isP[i]){for(int j=i*i;j<=1000000;j+=i)isP[j]=0;}
int num=0,flag=1;
for(int i=1;i<=1000000;++i)
if(isP[i]){
Prime[++num]=i,P[num]=P[num-1]+Prime[num];
}
// cout<<num<<endl;
for(int i=num+1;i<=10000000;++i)P[i]=0x7ffffffff;
int T,n,k;
int l,r,mid;
read(T);
while(T--){
read(n),read(k);
if(P[k]>n){
printf("-1
");
continue;
}
l=k,r=78498,ans=0,mid=0;
while(l<=r){
mid=(l+r)>>1;
if(can(mid,k,n))l=mid+1;
else r=mid-1;
}
if(ans)
printf("%d
",ans);
}
return 0;
}