Codeforces Round #614 (Div. 2)——A、B、C题题解

题目传送门:https://codeforces.com/contest/1293

A. ConneR and the A.R.C. Markland-N(思维+STL)

题目大意:

一栋楼有n层,每一层有个饭店,有一个现在在第s层,有k个层数的饭店关门了,问现在他要去最近的饭店吃饭最少要爬(或者下)几层楼。

解题思路:

因为n的值很大(1e9),所以不要想试图开一个数组去存,于是就想到了用STL去解决这个问题。本题有set和map两种方式去解决,我这里采用的是set。用一个set存被关闭的楼层(最多1000个),然后在集合中查找s+ans和s-ans(ans代表需要移动的楼层数,初始化为0),如果s+ans和s-ans同时查找到,就把ans++,因为我们要找的是最小移动楼层嘛。

AC代码:

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<set>
#include<string> 
#include<vector>
#include<stack>
#include<queue> 
#define PI 3.1415926
typedef long long ll;
using namespace std;
ll gcd(ll a, ll b) 
{
    if (b == 0) return a;
    else gcd(b, a % b);
}
const int inf=0x3f3f3f3f;
int main()
{
    int t;
    cin >> t;
    set<int> st;
    while(t--){
        st.clear();
        int n,s,k;
        cin >> n >> s >> k;
        while(k--){
            int a;
            cin >> a;
            st.insert(a);
        }
        int ans = 0;
        while((st.count(s + ans)||s + ans > n) && (st.count(s - ans)|| s - ans <=0)) ans ++;
        cout<<ans<<endl;

    }

}

B. JOE is on TV!(思维+贪心)

题目大意:

一个人去答题,他一共有s个对手,如果某一轮中有t个人答错了这道题,则那t个人被淘汰,他就能获得t/s的收益,最后只剩下一个人的时候游戏结束,问他最大的收益可能是多少(假设这个人能答对所有题目,也就是说最后剩的人一定是他)。

题目分析:

当每一轮只有1个人答错问题的时候他的收益能最大,为1/s+1/(s-1)+1/(s-2)+```+1
所以我们要计算的就是这个式子的值。

AC代码:

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<set>
#include<string> 
#include<vector>
#include<stack>
#include<queue> 
#define PI 3.1415926
typedef long long ll;
using namespace std;
ll gcd(ll a, ll b) 
{
    if (b == 0) return a;
    else gcd(b, a % b);
}
int main()
{
	double n=0,ans=0;
	cin>>n;
	while(n>0)
	{
		ans+=1/n;
		n--;
	}
	printf("%.12lf",ans);
	return 0;
}

C. NEKO’s Maze Game(思维)

题目大意:

有一个两行n列的2维数组,每一个位置都有通过和不通过两种状态,主人公只能上下左右走,不能斜着走,问在某种状态下主人公能不能从(1,1)走到(2,n)。如果这个格子的状态发生变化了,如果它原来的状态是能通过,就会变成不能通过,反之亦然。

题目分析:

因为只有两行,不能过的情况不外乎以下几种:1、上下两个格子均不能过.2、如果这个不能过的格子在第一行,那么它的左下方或者右下方45°也存在一个不能过的格子。3、如果这个不能过的格子在第二行,那么它的左上方或者右上方45°也存在一个不能过的格子。在这里插入图片描述
我们要设置一个临时变量cnt,用cnt表示此时不能通过的种类的数量,凡是通过变化能使得原本可达到不可达时,cnt就对应的加多少,凡是通过变化能使得原本不可达到可达时,cnt就对应的减多少。如果cnt==0,那么就表示可达,否则表示不可达。

AC代码:

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<set>
#include<string> 
#include<vector>
#include<stack>
#include<queue> 
#define PI 3.1415926
typedef long long ll;
using namespace std;
int main()
{
	ll n=0,q=0,cnt=0;
	cin>>n>>q;
	static ll a[3][100010]={0};
	memset(a,0,sizeof(a));
	while(q--)
	{
		ll x=0,y=0;
		scanf("%lld%lld",&x,&y);
		if(x==1)
		{
			if(a[x][y]==0)
			{
				a[x][y]=1;
				if(a[x+1][y]==1)
				cnt++;
				if(a[x+1][y+1]==1)
				cnt++;
				if(a[x+1][y-1]==1)
				cnt++;
		 	} 
		 	else
			{
				a[x][y]=0;
				if(a[x+1][y]==1)
				cnt--;
				if(a[x+1][y+1]==1)
				cnt--;
				if(a[x+1][y-1]==1)
				cnt--;
		 	} 
		}
		if(x==2)
		{
			if(a[x][y]==0)
			{
				a[x][y]=1;
				if(a[x-1][y]==1)
				cnt++;
				if(a[x-1][y+1]==1)
				cnt++;
				if(a[x-1][y-1]==1)
				cnt++;
		 	} 
		 	else
			{
				a[x][y]=0;
				if(a[x-1][y]==1)
				cnt--;
				if(a[x-1][y+1]==1)
				cnt--;
				if(a[x-1][y-1]==1)
				cnt--;
		 	} 
		}
		if(cnt==0)
		cout<<"Yes"<<endl;
		else
		cout<<"No"<<endl;
	}		
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值