牛客小白月赛67

牛客小白月赛67

A 画牌河

思路:模拟
按题目模拟就行

#include
using namespace std;
int main(){
    int n;std::cin>>n;
    for(int i=1;i<=3;i++){
        for(int j=1;j<=6;j++){
            if(n){
                std::cout<<1;
                n--;
            }
            else std::cout<<0;
        }
        std::cout<<"\n";
    }
}

B 不点两面(easy version)

思路:暴力枚举
因为这是简单版本所以之间暴力即可,标记当前位置出现的次数,然后遍历1到m那些点能到标记的点记录下来即可

#include 
#include 
#define endl "\n"
using namespace std;

typedef long long LL;
const int N = 110;

int m, q;
int cnt[N];

void solve()
{
	cin >> m >> q;
	while(q--)
	{
		int op, x;
		cin >> op >> x;
		if(op - 1) cnt[x]--;
		else cnt[x]++;
		int ans = 0;
		for(int i = 1; i <= m; i++) 
		{
			if(i > 3 && cnt[i - 3])  ans++;
			else if(i + 3 <= m && cnt[i + 3]) ans++;
		}
		cout << ans << endl;
	}
}
int main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	solve();
    return 0;
}

C 一刀二分三角

思路:数学

我们可以,以C点的x坐标(Xc)来划分左右两段

如果符合条件出现在左边(0 -> Xc)就输出YES,

如果不存在左边那就去判断是否存在右边(Xc -> Xb)(包括中间的Xc),

如果右边符合条件就输出YES,不然就符合条件输出NO
牛客小白月赛67_第1张图片
通过相似三角形可以推出等式2ii=xc*xb;
右边同理,只是xc变为xb-xc即可

#include
using namespace std;
int main(){
    int t;std::cin>>t;
    while(t--){
        int xb,xc,yc;std::cin>>xb>>xc>>yc;
        int f=0;
        for(int i=0;i=xc;i--){
                if(i*i*2==xb*(xb-xc))f=1;
            }
        }
        if(f)std::cout<<"YES\n";
        else std:cout<<"NO\n";
    }
}

D 不点两面(hard version)

思路:预处理
这个相比简单的他的数据变大了,之间暴力不行了,我这里分享的是预处理两个维度,第一维度是答案。第二维度当前处于安全的点的次数,然后没错输出答案即可

#include 
#include 
#define endl "\n"
using namespace std;

typedef long long LL;
const int N = 3e6;

int m, q;
int cnt[N];
bool st[N];
void solve()
{
	cin >> m >> q;
    int res=0;
	while(q--)
	{
		int op, x;
		cin >> op >> x;
		if(op - 1) {
            if(x-3>0){
                cnt[x-3]--;
                if(!cnt[x-3])res--;
                
            }
            if(x+3<=m){
                cnt[x+3]--;
                if(!cnt[x+3])res--;
            }
        }
		else {
            if(!cnt[x-3]&&x-3>0){
                
                res++;
            }
            if(x-3>0){
                
                cnt[x-3]++;
            }
            if(!cnt[x+3]&&x+3<=m){
                //cout<<"--" <

E 游戏的买

思路:动态规划
这道题要注意一定要保证游戏能够买到。如何在最优的情况下保证能够买到游戏,正面考虑太复杂了,我们倒着考虑,创建一个数组f用来记录,从第i开始到最后的最优的期望,对于f[n]也就是最后一天,马上就要停止发售了,所以必须要购买,所以这天的期望是0.5a+0.5b,那么对于一般的情况,例如i,我们已经知道了从i+1天开始购买的最佳的期望f[i+1],如何算出从第i天开始的最佳的期望,如果说,第i天不管购买a还是b都是不如之后购买的期望,那么f[i]=f[i+1],如果说第i天不管购买a还是购买b都是比之后购买要更好,那么肯定不会选择再之后购买,所以最好的期望就是0.5a+0.5b,如果说a

#include
using namespace std;
#define int long long
const int N=2e5;
int a[N],b[N];
double dp[N];
int t,n;
void solve(){
    std::cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int j=1;j<=n;j++)cin>>b[j];
    dp[n]=(a[n]+b[n])*0.5;
    for(int i=n-1;i>=1;i--){
        if(min(a[i],b[i])>=dp[i+1])dp[i]=dp[i+1];
        else if(max(a[i],b[i])>t;
    while(t--)solve();
}

你可能感兴趣的:(算法,数据结构)