AtCoder Beginner Contest 181 A-F 全部题目解析

A:奇数输出Black,偶数输出White即可。。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
//#define m (l+r)/2
#define pb push_back
typedef pair<int,int> pii;
const double PI= acos(-1.0);
const int M = 1e5+7;
/*
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/

int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	int n ;
  	cin>>n;
  	if(n&1)cout<<"Black"<<endl;
  	else cout<<"White"<<endl;
  	
	return 0;
}

B: 枚举+等差数列算一下即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
//#define m (l+r)/2
#define pb push_back
typedef pair<int,int> pii;
const double PI= acos(-1.0);
const int M = 1e5+7;
/*
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/

int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	int n ;
  	cin>>n;
  	ll ans=0;
  	for(int i=1;i<=n;i++){
  		ll a,b;
  		cin>>a>>b;
  		ans+=(a+b)*(b-a+1)/2;
	  }
  	cout<<ans<<endl;
	return 0;
}

C:

枚举三点,用斜率公式算下是否相同即可。注意转成相乘判断!

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
//#define m (l+r)/2
#define pb push_back
typedef pair<int,int> pii;
const double PI= acos(-1.0);
const int M = 1e2+7;
/*
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
int x[M],y[M];
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	int n ;
  	cin>>n;
  	for(int i=1;i<=n;i++){
  		cin>>x[i]>>y[i];
  		
	  }
	  bool flag=false;
	for(int i=1;i<=n;i++){
		for(int j=i+1;j<=n;j++){
			for(int k=j+1;k<=n;k++){
				if((x[i]-x[j])*(y[k]-y[j])==(y[i]-y[j])*(x[k]-x[j])){
				//	cout<<i<<" "<<j<<" "<<k<<endl;
					flag=true;
				}
			}
		}
	}
	if(flag)cout<<"Yes"<<endl;
	else cout<<"No"<<endl;
	return 0;
}

D:

只需要判断出现的数能否组成3位数以内被8整除的数即可。

大于3位数一定能被1000整除,也就是被8整除。

然后就暴力判断即可。最多才1000次运行。。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
//#define m (l+r)/2
#define pb push_back
typedef pair<int,int> pii;
const double PI= acos(-1.0);
const int M = 2e5+7;
/*
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
char s[M];
int mp[11];
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	cin>>s;
  	int n=strlen(s);
  	for(int i=0;i<n;i++)mp[s[i]-'0']++;
  	if(n==1){
  		if(s[0]=='8')cout<<"Yes"<<endl;
  		else cout<<"No"<<endl;
  		return 0;
	  }
	if(n==2){
		for(int i=0;i<=9;i++)
  		for(int j=0;j<=9;j++){
  				mp[i]--,mp[j]--;
  				if(mp[i]<0||mp[j]<0){
  					mp[i]++,mp[j]++;
  					continue;
				  }
  				if((i*10+j)%8==0){
  					cout<<"Yes"<<endl;
  					return 0;
				  }
				mp[i]++,mp[j]++;
			  }
		cout<<"No"<<endl;
		return 0;
	}
  	for(int i=0;i<=9;i++)
  		for(int j=0;j<=9;j++)
  			for(int k=0;k<=9;k++){
  				mp[i]--,mp[j]--,mp[k]--;
  			/*	if(i==4&&j==0&&k==0){
  					cout<<"oji"<<endl;
				  }*/
  				if(mp[i]<0||mp[j]<0||mp[k]<0){
  					mp[i]++,mp[j]++,mp[k]++;
  					continue;
				  }
  				if((i*100+j*10+k)%8==0){
  					cout<<"Yes"<<endl;
  					return 0;
				  }
				mp[i]++,mp[j]++,mp[k]++;
			  }
	cout<<"No"<<endl;
	return 0;
}

E:

比较显然:枚举W数组插在h数组哪个位置,然后算结果即可。

注意要提前预处理某个位置前偶数位-奇数位的差值和,和某个位置后奇数位-偶数位的差值和。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
//#define m (l+r)/2
#define pb push_back
typedef pair<int,int> pii;
const double PI= acos(-1.0);
const int M = 4e5+7;
/*
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
ll h[M],w[M];
ll pr1[M],pr2[M],nt1[M],nt2[M];
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	int n,m;
  	cin>>n>>m;
  	for(int i=1;i<=n;i++){
  		cin>>h[i];
	  }
	for(int i=1;i<=m;i++)cin>>w[i];
	sort(h+1,h+1+n);
	sort(w+1,w+1+m);
	for(int i=1;i<=n;i+=2){
		if(i+1<=n)pr1[i]=pr1[i+1]=pr1[i-1]+h[i+1]-h[i];
//		if(i-1>=1)pr2[i]=pr2[i-1]=pr2[i-2]+h[i]-h[i-1]; 
	//	cout<<i<<" "<<pr1[i]<<endl;
	}
	for(int i=n;i>=1;i-=2){
	//	if(i+1<=n)nt1[i]=nt1[i+1]=nt1[i+2]+h[i+1]-h[i];
		if(i-1>=1)nt2[i]=nt2[i-1]=nt2[i+1]+h[i]-h[i-1]; 
	}
	int nw=1;
	ll mn=2e18;
	for(int i=1;i<=n;i++){
		while(nw<=m&&w[nw]<=h[i]){
			ll ans=0;
			if(i&1){
				ans+=pr1[i-1];
				ans+=nt2[i+1];
				ans+=h[i]-w[nw];
			}else{
				if(i-2>0)ans+=pr1[i-2];
				ans+=nt2[i+1];
				ans+=w[nw]-h[i-1];
			}
		//	cout<<i<<"  - "<<pr1[i-2]<<" -> "<<nt2[i+1]<<" = = "<<ans<<endl;
			mn=min(mn,ans);
			nw++;
		}
	}
	while(nw<=m){
		mn=min(mn,pr1[n-1]+w[nw]-h[n]);
	//	cout<<" == "<<mn<<endl;
		nw++;
	}
	cout<<mn<<endl;
	return 0;
}

F:

经典套路了,这种判断一个圆是否能通过障碍物,或者给若干个圆,问是否有空隙,等问题均可用并查集处理。

对于这题,显然可以二分圆的半径。

然后对于任意两个钉子A、B,若AB距离小于圆的直径,则圆不能穿过他们,那么就把他们并到一个集合里。

处理完任意两个钉子后,再把所有钉子与上界和下届进行判断是否要并入一个集合。

最后如果上界和下届属于一个集合,则说明不存在一个方案使得直径为当前情况的圆穿过。

否则则存在。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
//#define m (l+r)/2
#define pb push_back
typedef pair<int,int> pii;
const double PI= acos(-1.0);
const int M = 1e5+7;
/*
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
double eps = 1e-7;
int n;
double x[110],y[110];
double dis(double x1,double y1,double x2,double y2){
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int fa[210];
int gt(int x){
	if(x==fa[x])return x;
	return fa[x]=gt(fa[x]); 
}
bool ck(double r){
	for(int i=1;i<=n+2;i++)fa[i]=i;	
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(dis(x[i],y[i],x[j],y[j])+eps<=2*r)
				fa[gt(i)]=gt(j);
		}
		if(100-y[i] + eps<=2*r)fa[gt(i)]=gt(n+1);
		if(y[i]+100 + eps<=2*r)fa[gt(i)]=gt(n+2);
	}
	if(gt(n+1)==gt(n+2))return false;
	return true;
}
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	cin>>n;
  	for(int i=1;i<=n;i++){
  		cin>>x[i]>>y[i];
	}
	double l=0,r=100,ans=0;
	while(l+eps<=r){
		double mid=(l+r)/2;
		if(ck(mid))l=mid,ans=mid;
		else r=mid;
	}
	cout<<ans<<endl;
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值