小白月赛72(3/6)补DE

昨天打了场小白月赛,前3题出题极慢,还wa了一发,最终过了三题,排名470/1500,rating加了5分,差点扣分....现rating1231,继续加油啊;

A:登录—专业IT笔试面试备考平台_牛客网

md,A题看题意看了好久,一直在想第n个平台是哪一个平台还是全部的平台啊,其实第n的平台中的n就是我们输入的,我真是傻子....

我们只需要考虑第一个平台和第n个平台的高度即可
 

#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#include<stack>
#include<deque>
#include<vector>
#include<map>
#include<set>
#include <utility>
using namespace std;
typedef  long  long ll ;
#define pii pair<int,int>
const int inf = 0x3f3f3f3f;//106110956
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;
}
void print(__int128 num) {
	if(num) {
		print(num/10);
		putchar(num%10+'0');
	}
}
int n;
int a[100005]; 
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	if(a[1]>=a[n]){
		printf("NO\n");
	}else{
		printf("YES\n");
	}

	return 0;
}

B:登录—专业IT笔试面试备考平台_牛客网

这题我一下下去就有了思路了,因子的个数为奇数的数一定是完全平方数,即(int)sqrt(i)*(int)sqrt(i)=i;然后我就想了想,有没有i不是完全平方数,但(int)sqrt(i)*(int)sqrt(i)=i的数呢;

想了想应该是没有的..

然后就交了,就ac了

#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#include<stack>
#include<deque>
#include<vector>
#include<map>
#include<set>
#include <utility>
using namespace std;
typedef  long  long ll ;
#define pii pair<int,int>
const int inf = 0x3f3f3f3f;//106110956
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;
}
void print(__int128 num) {
	if(num) {
		print(num/10);
		putchar(num%10+'0');
	}
}
int t;
int main(){
	int n;
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		int cnt=0;
		for(double i=1;i<=n;i++){
			int m=sqrt(i);
			if(m*m==i)cnt++;
		}
		printf("%d\n",cnt);
	}


	return 0;
}

C:登录—专业IT笔试面试备考平台_牛客网

这题其实并不难,其实abc都不难,md我一直知不道样例是怎么出来的,所以读题读了好久,一开始我以为1≤i<j≤n,但是题目是1≤i,j≤n,i和j只要不相等即可,我真的是傻x...

然后看代码即可

#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#include<stack>
#include<deque>
#include<vector>
#include<map>
#include<set>
#include <utility>
using namespace std;
typedef  long  long ll ;
#define pii pair<int,int>
const int inf = 0x3f3f3f3f;//106110956
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;
}
void print(__int128 num) {
	if(num) {
		print(num/10);
		putchar(num%10+'0');
	}
}
int n;
int a[100005];
int b[100005];
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	for(int i=1;i<=n;i++){
		scanf("%d",&b[i]);
	}
	ll ans1=0;
	ll ans2=0;
	for(int i=1;i<=n;i++){
		if(a[i]-b[i]<=0){
			ans1=ans1+abs(a[i]-b[i]);
		}else{
			ans2=ans2+a[i]-b[i];
		}
	}
	if(ans1==ans2){
		printf("%lld\n",ans1);
	}else{
		printf("-1\n");
	}
	
	return 0;
}

D:登录—专业IT笔试面试备考平台_牛客网

这题开始的时候我一直思考用搜索好呢还是用dp呢...看到n和m的范围我感觉搜索一定会超时,所以我感觉用dp,一开始我是把传送门排序的,但是想了一会,发现排序不一定是最优的,比如(x1,y1)和(x2,y2),因为宝藏有正有负,而且如果宝藏是正的,也不一定满足我们的理想条件,即x1<=x2&&y1<=y2。但是传送门的个数很小,所以可以枚举

我们需要统计的是(1,1)->(n,m)和(1,1)->(x1,y1)->(x2,y2)->(n,m)的最值

我比赛的时候写的是(1,1)->(n,m)和(1,1)->(n,m)+(x1,y1)->(x2,y2)的最值

我们用dp[i][j]来存储(1,1)到(x1,y1)的最值

用dp1[i][j]来存储(x2,y2)到(n,m)的最值

	dp1[n][m]=a[n][m];
	for(int i=n;i>=1;i--){
		for(int j=m;j>=1;j--){
			if(i==n&&j==m)continue;
			dp1[i][j]=max(dp1[i+1][j],dp1[i][j+1])+a[i][j];
		}
	}

dp1是倒着循环的,如果正着循环的话,dp1对于每一个(x2,y2)都需要循环一次;

倒着循环的话,我们只需要循环一次即可;‘

注意ans要赋值为dp[n][m],因为我们还可以不采用传送门的情况

#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#include<stack>
#include<deque>
#include<vector>
#include<map>
#include<set>
#include <utility>
using namespace std;
typedef  long  long ll ;
#define pii pair<int,int>
const int inf = 0x3f3f3f3f;//106110956
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;
}
void print(__int128 num) {
	if(num) {
		print(num/10);
		putchar(num%10+'0');
	}
}
int n,m;
ll dp[1005][1005]; 
ll dp1[1005][1005];
int a[1005][1005];
struct Node{
	int x,y;
}b[10];
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			scanf("%d",&a[i][j]);
		}
	}
	int t;
	scanf("%d",&t);
	memset(dp,-inf,sizeof(dp));
	memset(dp1,-inf,sizeof(dp1));
	
	dp[1][1]=a[1][1];	
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(i==1&&j==1)continue;
			dp[i][j]=max(dp[i-1][j],dp[i][j-1])+a[i][j];
		}
	} 
	
	dp1[n][m]=a[n][m];
	for(int i=n;i>=1;i--){
		for(int j=m;j>=1;j--){
			if(i==n&&j==m)continue;
			dp1[i][j]=max(dp1[i+1][j],dp1[i][j+1])+a[i][j];
		}
	}
	
	while(t--){
		int k;
						
		scanf("%d",&k);
				
		for(int i=1;i<=k;i++){
			scanf("%d%d",&b[i].x,&b[i].y);
		}
		
		ll ans=dp[n][m];//不要忘记可以不用传送门的情况 
		for(int i=1;i<=k;i++){//传送的地方 
			for(int j=1;j<=k;j++){//传到的地方 
				if(i==j)continue;	
				ans=max(ans,dp[b[i].x][b[i].y]+dp1[b[j].x][b[j].y]);
			}
			
		}
		
		printf("%lld\n",ans);
		
	}
	
	return 0;
}

E:登录—专业IT笔试面试备考平台_牛客网 

这题比赛的时候没有做,赛后补的,如果做的话,也做不出来啊

我的思路:暴力双层循环,铁定会超时,二分也没想出来怎么做..

正确:二分答案+双指针思想

将a和b从小到大排序,然后如图,枚举i,然后如果while(a[i]*b[r]>mid&&r)r--;

cnt=cnt+r;

对于二分,因为注意等于要在right=mid-1的情况写,因为mid可能不存在,如果不存在的话,right=mid-1;

对于不能在一起的食物和烹饪方法,我们提前把他们入vector,然后如果vector里的数小于mid,

cnt--即可;

ll check(ll mid){
	int r=m;
	ll cnt=0;
	for(int i=1;i<=n;i++){
		while(a[i]*b[r]>mid&&r)r--;
		cnt=cnt+r;
	}
	for(int i=0;i<k;i++){
		if(s[i]<=mid){
			cnt--;
		}
	}
	return cnt;
}
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#include<stack>
#include<deque>
#include<vector>
#include<map>
#include<set>
#include <utility>
using namespace std;
typedef  long  long ll ;
#define pii pair<int,int>
const int inf = 0x3f3f3f3f;//106110956
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;
}
void print(__int128 num) {
	if(num) {
		print(num/10);
		putchar(num%10+'0');
	}
}
int n,m,k,q;
int a[1000006];
int b[1000006];
vector<ll>s;
ll check(ll mid){
	int r=m;
	ll cnt=0;
	for(int i=1;i<=n;i++){
		while(a[i]*b[r]>mid&&r)r--;
		cnt=cnt+r;
	}
	for(int i=0;i<k;i++){
		if(s[i]<=mid){
			cnt--;
		}
	}
	return cnt;
}
int main(){
	scanf("%d%d%d%d",&n,&m,&k,&q);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]); 
	}
	for(int i=1;i<=m;i++){
		scanf("%d",&b[i]); 
	}
	int x,y;
	for(int i=1;i<=k;i++){
		scanf("%d%d",&x,&y);
		s.push_back(a[x]*b[y]);
	}
	
	sort(a+1,a+1+n);
	sort(b+1,b+1+m);
	
	while(q--){
		int x;
		scanf("%d",&x);
		ll right=1e15;
		ll left=0;
		while(left<=right){
			ll mid=(left+right)/2;
			if(check(mid)>=x){
				right=mid-1;
			}else{
				left=mid+1;
			}
		}
		printf("%lld\n",right+1);
	}
	
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值