北华大学第九届程序设计竞赛(同步赛)(5/13)

这场比赛是学长组织的,我们打了重现赛,除了我一个人外其他人都是组队打的,省赛队友一直在摆烂,有时间也不来比赛,我们还是正式队伍呢,伤心死了...

总结一下,一个人打5个小时还是比较累的,一个人思考,一个人改错,而且不跟别人交流自己的思维会慢慢的下来。

B:https://ac.nowcoder.com/acm/contest/57773/B

这题一开始想的做法是O(nm),我想着可能碰巧过,所以我就试了试,结果没过,然后就啥啥思路了,做别的签到题了,然后作完签到题之后就又开始做这道题目了,想到了一个前缀和的做法,不过开一个1e8的long long数组,爆了内存了,然后就没啥思路了.....

正确思路:二分查找:

已知O(nm)铁定会超时和n和m的范围,所以至少O(nlogm)或者O(mlogn)是能过的

这样就很好想到二分了        

在输入完a数组之后,对a进行排序,统计a的前缀和

然后遍历b数组,查找第一个大于b[i]的位置x,(lower_bound()或者upper_bound()函数)x位置之前的格子数即为s[x-1],x之后的格子即为吧b[i]*(n-x+1)

#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');
	}
}
ll ex_gcd(ll a,ll b,ll& x,ll& y){
	if(b==0){
		x=1;
		y=0;
		return a;
	}

	ll d=ex_gcd(b,a%b,y,x);
	y=y-a/b*x;
	return d;
}
int n,m;
int a[300005];
ll b[300005]; 
ll s[300005];
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){	
		scanf("%d",&a[i]);
	}
	sort(a+1,a+1+n);
	
	for(int i=1;i<=n;i++){
		s[i]=s[i-1]+a[i];
	}
	
	scanf("%d",&m);
	ll ans=0;
    	
	for(int i=1;i<=m;i++){
		scanf("%lld",&b[i]);
		int cnt=upper_bound(a+1,a+1+n,b[i])-a;
		ans=ans+s[cnt-1]+(n-cnt+1)*b[i];

	}
	printf("%lld\n",ans);

	return 0;
}


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

这题其实就是个模拟,一开始思路还是不是很清楚就开始做题了,

然后就出现各种情况;

其实情况就有一下几种:

1.一开始钱够能买精炼器并且能买发电站(电不够的情况下)

2.一开始钱不够用,买不了精炼器和发电站,在挖一段时间后才买的

3.挖完矿也不能买精炼器和发电站

4.钱够用但是d+D>E,并且e=0(比赛的时候就这一点没想到,然后就错了,真的很可惜啊)

这是我比赛时候写的,写的异常麻烦

	#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');
		}
	}
	ll ex_gcd(ll a,ll b,ll& x,ll& y){
		if(b==0){
			x=1;
			y=0;
			return a;
		}
	
		ll d=ex_gcd(b,a%b,y,x);
		y=y-a/b*x;
		return d;
	}
	int t ;
	double w,m,E,D,c0,d,c1,e;
	double p;
	int main(){
		scanf("%d",&t);
		while(t--){
			cin>>w>>m>>E>>D>>c0>>d>>p>>c1>>e;
			//w为总价值,m为现在有的钱 
			double ans=w+m;
			if(m>=c0){	
				if(d+D<=E){
					ans=max(ans,m-c0+w*(1+p/100));
				}else{
					if(e!=0){
						if((D+d-E)/e==int((D+d-E)/e)){	
						int k=(D+d-E)/e;
						if(k*c1<=m-c0){
							ans=max(ans,m-c0-k*c1+w*(1+p/100));
							}
						}else{
							int k=(D+d-E)/e+1;
							if(k*c1<=m-c0){
							ans=max(ans,m-c0-k*c1+w*(1+p/100));
							}
						}
					}
					
					}	
				}
				int k=0;
				if((D+d-E)/e==int((D+d-E)/e)&&e){
					if(D+d-E>=0){
					k=(D+d-E)/e;
					}	
				}else{
					if(D+d-E>=0&&e){
						k=(D+d-E)/e+1;
					}				
				}		
				if(w+m>=c0+k*c1&&(m<c0+k*c1||m<c0)){	
					if(d+D<=E){
						ans=max(ans,(w-c0+m)*(1+p/100));
					}else{
						if(e!=0){
								if((D+d-E)/e==int((D+d-E)/e)){	
						int k=(D+d-E)/e;
						if(w+m>=c0+k*c1){
							ans=max(ans,(w+m-c0-k*c1)*(1+p/100));
							}
						}else{
							int k=(D+d-E)/e+1;
							if(w+m>=c0+k*c1){
							ans=max(ans,(w+m-c0-k*c1)*(1+p/100));
							}
						}
						}
					
						
					}	
					
				}			
			printf("%0.2lf\n",ans);	
		}	
		return 0;
	}

 补题:

比赛时候不知道ceil()函数,即求大于等于这个数的最小的数

floor()小于等于这个数的最大的数

round()四舍五入函数        

#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');
	}
}
ll ex_gcd(ll a,ll b,ll& x,ll& y){
	if(b==0){
		x=1;
		y=0;
		return a;
	}

	ll d=ex_gcd(b,a%b,y,x);
	y=y-a/b*x;
	return d;
}
double w,m,E,D,c0,d,p,c1,e;	
int t;
int main(){
	scanf("%d",&t);
	while(t--){
		cin>>w>>m>>E>>D>>c0>>d>>p>>c1>>e;
		double ans1=w+m;
		double nm=0;
		double ans2=0;
		if(e==0){
			if(d+D<=E){
				if(c0<=m){
					ans2=m-c0+w*(1+p/100);
				}else{
					ans2=(m-c0+w)*(1+p/100);
				}
				
			}else{
				ans2=m+w;
			}
		}else{
			nm=max(0.0,ceil((D+d-E)/e))*c1+c0;
			if(nm<=m){
				ans2=(m-nm)+w*(1+p/100);
			}else{						
				ans2=(m+w-nm)*(1+p/100);	
			}
		}	
		printf("%.2lf\n",max(ans1,ans2));
	}

	return 0;
}


G:这题我一开始想到了背包问题,然后又想到了线性dp,想了想两种方法好像都不对,然后就想了别的思路,然后就想到了这题登录—专业IT笔试面试备考平台_牛客网,然后想着怎么样去凑1这个数字,然后我想到了4*14-5*11=1

然后我比赛的时候是脑子是真的不清晰啊,因为题意说答案a,b,c都要<=1e9,然后我想到了5* n大于1e9的情况,然后,我就使得5n<=1e9

然后多出的部分用45来凑,那时想的是真麻烦

#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');
	}
}
ll ex_gcd(ll a,ll b,ll& x,ll& y){
	if(b==0){
		x=1;
		y=0;
		return a;
	}

	ll d=ex_gcd(b,a%b,y,x);
	y=y-a/b*x;
	return d;
}
ll n;
int a,b,c,A,B,C;
int main(){
	scanf("%d",&n);
	if(n*5>1e9){	
		for(int i=1;;i++){
			if(5*(n-45*i)<=1e9){
				A=5*(n-45*i);
				c=4*(n-45*i);
				b=i;
				break;
			}
		}
	}else{
		A=5*n;//11
		c=4*n;//14
	}
	printf("%d %d %d\n",a,b,c);// 11 . 45 .14
	 printf("%d %d %d\n",A,B,C);
	

	return 0;
}


即使5n超出1e9,我们可以先将n%45,然后在求11和14的数量,因为1可以表示任何数字

!!!

#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');
	}
}
ll ex_gcd(ll a,ll b,ll& x,ll& y){
	if(b==0){
		x=1;
		y=0;
		return a;
	}

	ll d=ex_gcd(b,a%b,y,x);	
	y=y-a/b*x;
	return d;
}
int n; 
int a,b,c,A,B,C;
int main(){
	scanf("%d",&n);
	b=n/45;
	n=n%45;
	c=4*n;
	A=5*n;
	printf("%d %d %d\n",a,b,c);
	printf("%d %d %d\n",A,B,C);


	return 0;
}


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

其实这题还是很简单的,然后就是自己想的不清晰,我发现我的老毛病,没想清楚就开始做题了,一开始我只想到了x==y的情况才会有过边界,然后有想了想,如果max(x,y)%min(x,y)==0的情况也会有过边界的情况,然后交了好几发都wa了,然后就想到了4,6这种情况,也会过边界,其实就是gcd(x,y)!=1的情况就会过边界

参考案例,很容易得出答案

#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');
	}
}
ll ex_gcd(ll a,ll b,ll& x,ll& y){
	if(b==0){
		x=1;
		y=0;
		return a;
	}

	ll d=ex_gcd(b,a%b,y,x);
	y=y-a/b*x;
	return d;
}
ll x,y;
int t;
int main(){
	scanf("%d",&t);	
	while(t--){				
		scanf("%d%d",&x,&y);		
		printf("%d\n",x+y-(__gcd(x,y)));
		
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值