DAY 2

预计得分 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;
}
原文地址:https://www.cnblogs.com/qdscwyy/p/7750722.html