2022年通师高专天梯赛选拔赛 题解

嘿嘿,今天打了一场比赛,写个题解吧!

A-扫雷:

传送门:扫雷

思路:本题是字符串纯模拟题,运用二维数组全遍历即可。

#include<iostream>
#include<stdio.h>
#include<fstream>
#include<algorithm>
#include<cmath>
#include<deque>
#include<vector>
#include<queue>
#include<string>
#include<cstring>
#include<map>
#include<stack>
#include<set>
#define int long long int
using namespace std;
char arr[1002][1002]={0};
signed main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
    	for(int j=1;j<=m;j++)
        {
        	cin>>arr[i][j];
		}
	}    
    for(int i=1;i<=n;i++)
	{
        for(int j=1;j<=m;j++)
		{
            int sum=0;
            if(arr[i-1][j-1]=='*')
			{
				sum++;
			}
            if(arr[i-1][j]=='*')
			{
				sum++;
			}
            if(arr[i][j-1]=='*')
			{
				sum++;
			}
            if(arr[i-1][j+1]=='*')
			{
				sum++;
			}
            if(arr[i+1][j]=='*')
			{
				sum++;
			}
            if(arr[i][j+1]=='*')
			{
				sum++;
			}
            if(arr[i+1][j+1]=='*')
			{
				sum++;
			}
            if(arr[i+1][j-1]=='*')
			{
				sum++;
			}
			if(arr[i][j]!='*')
			{
				cout<<sum;
			}
			else
			{
				cout<<'*';
			}
        }
        cout<<endl;
    }
	return 0;
}

B-3和5和7

传送门:3和5和7

思路:for循环从1到n进行判断即可

#include<iostream>
#include<stdio.h>
#include<fstream>
#include<algorithm>
#include<cmath>
#include<deque>
#include<vector>
#include<queue>
#include<string>
#include<cstring>
#include<map>
#include<stack>
#include<set>
#define int long long int
using namespace std;

signed main()
{
    int t;
    cin>>t;
	for(int i=0;i<=t;i++)
	{
		if(i%3==2&&i%5==3&&i%7==2)
		{
			cout<<i<<endl;
		}
	}
	return 0;
}

C-苦逼的单身狗

传送门:苦逼的单身狗

思路:遍历字符串,记录出现"LOVE"四字母时下标,当四字母均遍历到,然后去最小的ans+最小下标再加1 因为当四字母均有时 假设遍历到最后四字母最后一个剩余的时候结束,那么此时满足题意的情况是,最小下标加1种。

#include<iostream>
#include<stdio.h>
#include<fstream>
#include<algorithm>
#include<cmath>
#include<deque>
#include<vector>
#include<queue>
#include<string>
#include<cstring>
#include<map>
#include<stack>
#include<set>
#define int long long int
using namespace std;

signed main()
{
    int t;
    cin>>t;
	while(t--)
	{
		string s;
		cin>>s;
		int len=s.size();
		int ans=0,l=-1,o=-1,v=-1,e=-1;
		int minn;
		for(int i=0;i<len;i++)
		{
			if(s[i]=='L')
			{
				l=i;	
			}
           	if(s[i]=='O')
			{
			   	o=i;
			}
          	if(s[i]=='V')
			{
			  	v=i;
			}
         	if(s[i]=='E')
			{
				e=i;
			}
         	minn=min(min(l,o),min(v,e));
         	if(minn!=-1)
			{
			 	ans+=minn+1;
			}
        }
        cout<<ans<<endl;
	}
	return 0;
}

D-小乐乐的组合数

传送门:小乐乐的组合数

思路:双重循环全遍历,%7判断即可;

#include<iostream>
#include<stdio.h>
#include<fstream>
#include<algorithm>
#include<cmath>
#include<deque>
#include<vector>
#include<queue>
#include<string>
#include<cstring>
#include<map>
#include<stack>
#include<set>
#define int long long int
using namespace std;

signed main()
{
    int t,n,sum=0;
    cin>>t>>n;
	for(int i=1;i<=t;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if((i+j)%7==0)
			{
				sum++;
			}
		}
	}
	cout<<sum;
	return 0;
}

E-丢手绢

传送门:丢手绢

思路:我们先去找距离第一个小朋友最远的小朋友i的位置,第i个小朋友与第一个小朋友之间的距离一定会是刚好过圆周长的一半或刚好没过一半,如果他过半了,则第i+1个小朋友与第一个小朋友的距离一定不会是答案,因为越向后就会离的越近,所以我们就去看第二个小朋友与第i个小朋友的距离,比第一个与第i个的距离,如果这个距离是刚好过半或准备要过半的状态,说明第i个小朋友是距离第二个小朋友最远的人,然后我们就去维护最大的距离。说白了,就是去找距离每个小朋友最远的那个小朋友,比出最大的距离就行。相当于拿了个尺子去卡这个不规则圆的最大“半径”。
 

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int a[100010]={0};
    int n;
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>a[i];
        a[i]+=a[i-1];//前缀和处理
    }
    int sum=a[n];
    int s=1,e=2;
    int mx=-1;
    while(e<=n&&s<e)
    {
        int dis1=a[e]-a[s];//求出第s个小朋友与第e个小朋友之间的距离
        int dis2=sum-dis1;
        mx=max(mx,min(dis1,dis2));
        if(dis1>dis2)
            s++;
        else
            e++;
    }
    cout<<mx;
    return 0;
}

F-华华给月月准备礼物

传送门:华华给月月准备礼物

思路:二分基础。确定枚举的左界L(初值取1),右界R(初值取最长的那根木棍长度),取区间中点mid,如果mid这个值作为最终的木棍长度可行,就说明小于mid的都可行,答案肯定是mid或者在右边,于是就可以缩小区间的范围了,相反的如果mid不可行,答案肯定在mid左边,这个时候修改r就好。区间变小之后重复这个操作,直到区间为空的时候就已经找到答案了。
 

#include<iostream>
#include<stdio.h>
#include<fstream>
#include<algorithm>
#include<cmath>
#include<deque>
#include<vector>
#include<queue>
#include<string>
#include<cstring>
#include<map>
#include<stack>
#include<set>
#define int long long int
using namespace std;
int a[200005];
signed main()
{
    int t,n,sum=0;
    cin>>t>>n;
    int l=1,r=0;
    for(int i=0;i<t;i++)
	{
		cin>>a[i];
		r=max(a[i],r);
	} 
	int mid;
	while(l<=r)
	{
		mid=(l+r)/2;
		int c=0;
		for(int i=0;i<t;i++)
		{
			c+=a[i]/mid;
			if(c>=n)
			{
				break;
			}
		}
		if(c<n)
		{
			r=mid-1;
		}
		else
		{
			l=mid+1;
		}
	}
	cout<<r;
	return 0;
}

G-Game

传送门:Game

思路:简单的博弈论。每次操作可以将集合中的一个数字分解为它的任意两个非1的因数, 集合中的数字个数+1。因为 质因数 是无法再被分解的,所以最后集合中的数全为 n 的质因数。因此只需要看题目给定的 n 有多少个质因数。假设 n 有 p 个质因数,那么这场游戏将进行 p-1 次操作(每次操作后集合中的数字个数+1),如果 p-1 为奇数那么后手便无法再进行操作,如果 p-1 为偶数则先手再无法进行操作。
 

#include<iostream>
#include<stdio.h>
#include<fstream>
#include<algorithm>
#include<cmath>
#include<deque>
#include<vector>
#include<queue>
#include<string>
#include<cstring>
#include<map>
#include<stack>
#include<set>
#define int long long int
using namespace std;

signed main()
{
    int t,c=0;
    cin>>t;
    int h=2;
    while(h<t)
    {
        if(t%h==0)
        {
            t=t/h;
            h=2;
            c++;
        }
        else
		{
			h++;
		} 
     }
    if(c%2==0)
    {
    	cout<<"Nancy";
	}
    else
    {
    	cout<<"Johnson";
	}
	return 0;
}

H-andy种树

传送门:andy种树

思路:这题的解法很多,dp,前缀和都可以。我用的是差分。

#include<iostream>
#include<stdio.h>
#include<fstream>
#include<algorithm>
#include<cmath>
#include<deque>
#include<vector>
#include<queue>
#include<string>
#include<cstring>
#include<map>
#include<stack>
#include<set>
#define int long long int
using namespace std;
int a[100005]={0};
signed main()
{
    int t,n;
    cin>>t>>n;
	while(n--)
	{
		int l,r;
		cin>>l>>r;
		a[l-1]++;
        a[r]--;
	}
    int ans=0;
	for(int i=0;i<t;i++)
	{
        ans+=a[i];
		cout<<ans<<" ";
	}
	return 0;
}

I-消减整数

传送门:消减整数

思路:让这个数x先直接减掉1,2,4…等,直到再减为负数为止,比如 31,先减去1 + 2 + 4 +8 = 16,而31 - 16 = 15。所以不能再减16。然后用cnt计数,目前减了4次。
2,然后还有15,在反过来减,15 - (8+4+2+1) = 0。正好等于0,但是由于这个数比较特殊,如果还有13,不是15的话,那么会发现13 - (8+2+1)=0;总之,反过来减一下就完了,如果减了小于0,那么cnt不变,原数也不变,此处减无效,如果不小于0,就可以减
 

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int cnt = 0;
        int x;
        cin>>x;

        int sum = 0;
        int i;
        for(i = 1;1;i*=2 )	//找正向乘最高的数。
        {
            sum += i;
            cnt++;
            if(sum+i*2>x) break;
        }
        x-=sum; 	//剩下的数
        while(x)	
        {
            if(x-i>=0)	//观察是否跳过该数
            {
                x-=i;
                cnt++;
            }
            i/=2;
        }


        cout<<cnt<<endl;
    }


    return 0;
}

J-数字比较

传送门:数字比较

思路:10的9次方的10的9次方的结果int是不可能存下的,所以我们运用高中数学的思路把幂改成log运算即可。

#include<iostream>
#include<stdio.h>
#include<fstream>
#include<algorithm>
#include<cmath>
#include<deque>
#include<vector>
#include<queue>
#include<string>
#include<cstring>
#include<map>
#include<stack>
#include<set>
#define int long long int
using namespace std;

signed main()
{
    int t,n;
    cin>>t>>n;
	double a,b;
	a=n*log(t);
    b=t*log(n);
	if(a==b)
	{
		cout<<"=";
	}
	else if(a>b)
	{
		cout<<">";
	}
	else
	{
		cout<<"<";
	}
	return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值