2022NYIST(计科ACM&TC)第一次招新赛题解

目录

A 摸奖( 开盒 简单版)

B 小飞棍又来喽~~(开盒困难版)

C 扭曲的电路

D 搬桌子

E 首当其冲为签到!!

G 小企鹅家的空调调温度(芝士企鹅)

H 数字游戏

I 搬砖大赛

J 积

K 算面积

L 阮见美容店

M LK 暗号


A 摸奖( 开盒 简单版)

这道题是经典的三道门概率问题(传送门:经典数学问题——三门问题(数据分析面试题)_仲长杰秀的博客-CSDN博客_三门问题),换之后的概率永远大于等于换之前,当且仅当没有盒子被打开的时候换不换的概率就是一样的了那么答案就很明显了。当m为零的时候换不换都一样,否则都要换。

ac代码:

#include<iostream>
using namespace std;
int main()
{
    int n,m;
    cin>>n>>m;
    if(m==0)
    {
        cout<<"no thing"<<endl;
    }
    else
    {
        cout<<"YES"<<endl;
    }
    return 0;
}

B 小飞棍又来喽~~(开盒困难版)

这道题承接上题也属于三道门问题,不同的是上题不需要求概率公式这题需要求。但是简单版能理解的话推出来公式也是非常简单的(bushi?)。其实就是高中学过的条件概率问题啦。p(a)=(n-1)/n(未被锁定盒子里面有小飞棍的总概率),p(b)=1/(n-m-1)(打开m个盒子后每个盒子所占总概率的份数)。那么显而易见最大概率公式为:p(a)*p(b)=(n-1)/((n-m-1)*n),再注意一下精度问题就好ok啦。

 ac代码:

#include<iostream>
using namespace std;
int main() {
     double n,m;
     cin>>n>>m;
     printf("%.6lf",((n-1.0)/n)*(1.0/(n-m-1.0)));
}

C 扭曲的电路

纯纯的模拟题,只要按照图去推导再结合位运算的知识就ok啦,这里就不过多解释了。

ac代码: 

#include<iostream>
using namespace std;
int main() {
	int a,b,c,d;
	cin>>a>>b>>c>>d;
	cout << (((a ^ b) & (c | d)) ^ ((b & c) | (a ^ d))) << endl;
}

D 搬桌子

 签到题,注意一下最后是从那一栋楼到那一栋楼就好了,注意一下最后的状态。

ac代码: 

#include<bits/stdc++.h>
using namespace std;
int main(){
	long long m,k,a,b,x;
	cin>>m>>k>>a>>b;
	if(m%k==0) x=m/k;
	else x=m/k+1;
	cout<<(a+b)*x<<endl;
	return 0;
}

E 首当其冲为签到!!

 这是一道模拟题,根据它的题意模拟一下就可以,可以运用哈希思想标记一下方向,走过之后更改方向就行了,并不是很难。

ac代码:

#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <stack>
#include <queue>

using namespace std;

int n,m,k,c,a[1009][1009];

int main()
{
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            scanf("%d",&a[i][j]);
        }
    }
    while(k--)
    {
        scanf("%d",&c);
        int ans=0,x=1,y=c;
        while(x<=n)
        {
            if(a[x][y]==1)
            {
                a[x][y]=2;
                y++;
            }
            if(a[x][y]==2)
                x++;
            if(a[x][y]==3)
            {
                a[x][y]=2;
                y--;
            }
        }
        printf("%d ",y);
    }
    return 0;
}

G 小企鹅家的空调调温度(芝士企鹅)

这是一道cf的思维题,不是很难(bushi),再次是有很多人写过题解的了,这里直接传送门:Codeforces Round #731 (Div. 3) E. Air Conditioners思维_半醒之间.的博客-CSDN博客

ac代码:

#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include <stdio.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<tuple>
#include<numeric>
#include<stack>
using namespace::std;
typedef long long  ll;
int n,t,q;
int a[300005];
int b[300005];
ll ans[300005];
ll min(ll x,ll y){
    if(x<y)
    return x;
    return y;
}
void solv(){
    cin>>n>>q;
    for (int i =0; i<=n; i++) {
        ans[i]=1e17+5;
    }
    for (int i =0; i<q; i++) {
        cin>>a[i];
    }
    for (int i =0; i<q; i++) {
        cin>>b[i];
    }
    for (int i =0; i<q; i++) {
        ans[a[i]]=min(ans[a[i]], b[i]);
    }
    for (int i =1; i<=n; i++) {
        if (ans[i]>ans[i-1]+1) {
            ans[i]=ans[i-1]+1;
        }
    }
    for (int i =n-1; i>0; i--) {
        if (ans[i]>ans[i+1]+1) {
            ans[i]=ans[i+1]+1;
        }
    }
    for (int i =1; i<=n; i++) {
        printf("%lld ",ans[i]);
    }printf("\n");
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(); cout.tie();
    cin>>t;
    while (t--) {
        solv();
    }
    return 0;
}


H 数字游戏

 这题可以二分或者利用数学解答,数据范围很大肯定是不能暴力的。

用二分就是板子:先搜索一个L让L*L>=a,然后再搜索一个R让R*R<=b最后让R-L+1就是最后答案喽。

数学思维也不是很难:先判断两边是不是能开方,能开方的话直接开方当成边界,不能的话让左边加一,右边直接sqrt(b)就好了;最后也是求出来一个L和一个R,答案就是R-L+1.

二分ac代码:

#include<iostream>
using namespace std;
typedef long long ll;
int main()
{
    ll t;
    cin>>t;
    while(t--)
    {
        ll a,b;
        cin>>a>>b;
        ll R=0,L=0;
        ll l=0,r=1e9;
        while(l<r)
        {
            ll mid=(l+r+1)>>1;
            if(mid*mid<=b) l=mid;
            else r=mid-1;
        }
        R=l;
        l=0,r=1e9;
         while(l<r)
        {
            ll mid=(l+r)>>1;
            if(mid*mid>=a) r=mid;
            else l=mid+1;
        }
        L=l;
        cout<<R-L+1<<endl;
}
    return 0;
}

数学ac代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<stack>
#include<queue>
#include<iomanip>
#include<algorithm>

const int N=1e5+5;
typedef long long ll;
using namespace std; 
unsigned long long a,b,n;

void slove(){
	cin>>a>>b;
	unsigned long long x=sqrt(a);
	unsigned long long y=sqrt(b);
	if(x*x==a) cout<<y-x+1<<endl;
	else cout<<y-x<<endl;
}

int main()
{
	int t;cin>>t;
	while(t--)
    slove();
    return 0;
}

I 搬砖大赛

贪心+差分;

贪心策略为若a[i]>a[i-1],计数器sum+=a[i]-a[i-1];

为啥这样贪心是对的腻?由于过于懒大家可以直接看原题题解,传送门:登录 - 洛谷

ac代码:

#include<bits/stdc++.h>
using namespace std;
int n,a[100005];
long long ans=0;
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)     cin>>a[i];
	for(int i=2;i<=n;i++)     if(a[i]>a[i-1]) ans+=a[i]-a[i-1];
	cout<<ans+a[1];
	return 0;
}

J 积

签到题,直接判断一下就可(别傻傻的忘了换行),不过多赘述了,直接上代码。 

ac代码:

#include<iostream>
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
       int a,b,c;
        cin>>a>>b>>c;
        if(a*b==c||a*c==b||b*c==a) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
}

K 算面积

 这是道思维题,可以从六个方向的视图看他每个视图都有多大面积,最后加到一起就可以了。

ac代码: 

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<map>
#include<math.h>
#include<string.h>
#include<vector>
using namespace std;
typedef long long ll;
int mp[1005][1005];
int main(){
	int a,b,c,d;
	cin>>a>>b>>c>>d;
	int x=max(a,c)+max(b,d);
	int y=max(a,b)+max(c,d);
	int z=0;
	if(a!=0) z++;
	if(b!=0) z++;
	if(c!=0) z++;
	if(d!=0) z++;
	cout<<(x+y+z)*2<<endl;
	return 0;
}

L 阮见美容店

这是一道19年蓝桥杯初赛原题,用贪心思想就ok;

俺太懒了,直接来传送门吧:[蓝桥杯2019初赛]外卖店优先级_凯撒袁六兽的博客-CSDN博客

ac代码:

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
struct node
{
    int ts,num;
}a[N];
bool cmp(node s1,node s2)
{
    if(s1.ts==s2.ts)return s1.num<s2.num;
    return s1.ts<s2.ts;
}
int n,m,t,ans;
int last[N],sum[N];//第几号店的上一次时间,记录当前第几号店的值
bool st[N];//是否在优先缓存队列中
int main()
{

    int tt=0;//记录上一个时间
    scanf("%d%d%d",&n,&m,&t);
    for(int i=1;i<=m;i++)scanf("%d%d",&a[i].ts,&a[i].num);
    sort(a+1,a+1+m,cmp);
    for(int i=1;i<=m;i++)
    {
        int tt,id;
        tt=a[i].ts;id=a[i].num;
        if(tt!=last[id])sum[id]-=tt-last[id]-1;
        if(sum[id]<0)sum[id]=0;
        if(sum[id]<=3)st[id]=0;
        sum[id]+=2;
        if(sum[id]>5)st[id]=1;
        last[id]=tt;
    }
    for(int i=1;i<=n;i++)
    {
        if(last[i]<t)sum[i]-=t-last[i];
        if(sum[i]<=3)st[i]=0;
    }
    for(int i=1;i<=n;i++)
    {
        if(st[i])ans++;
    }
    cout<<ans<<endl;
    return 0;
}

M LK 暗号

这是一道思维+字符串的题,如果正向遍历字符串的话会很麻烦,那我们为什么不反向遍历字符串呢?先反向遍历字符串,然后再保存解密后的字符,再反向输出就行了。

ac代码:

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
char a[1005],s[1005];
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n,p=0;
		cin>>n;
		cin>>s;
		for(int i=n-1;i>=0;i--)
		{
			if(s[i]=='0')
			{
				int cnt1=(s[i-1]-'0')+(s[i-2]-'0')*10;
				a[p++]=cnt1-1+'a';
				i-=2;
			}
			else 
			{
				a[p++]=s[i]-'0'-1+'a';
			}
		}
		for(int i=p-1;i>=0;i--)
		cout<<a[i];
		cout<<endl;
		memset(a,0,sizeof(a));
		memset(s,0,sizeof(s));
	}
	return 0;
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值