HNCU周赛 hello 2023

周赛链接

A

  • 水题,杨辉三角

两种方法

  1. 直接打表,本题数据不大, n = 20 n=20 n=20,故如果不会例举出来打表即可

打表思路简单,所以不给出代码

  1. 模拟即可,找出规律
  • a ( i , j ) = a ( i − 1 , j − 1 ) + a ( i − 1 , j ) ( i > 1 , 1 < j < = i ) a(i,j)=a(i-1,j-1)+a(i-1,j)(i>1,1<j<=i) a(i,j)=a(i1,j1)+a(i1,j)(i>1,1<j<=i)
#include<bits/stdc++.h>
int a[21][21];
using namespace std;
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	a[i][1]=a[i][i]=1;
	for(int i=1;i<=n;i++)
	{
		for(int j=2;j<i;j++)
		{
			a[i][j]=a[i-1][j-1]+a[i-1][j];
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=i;j++)
		{
			cout<<a[i][j]<<" ";
		}
		cout<<endl;
	}
}

B

  • 高精度,这道题出来了好几次了
  • 由于 i n t int int最大只能开 1 e 9 1e9 1e9,而就算是$ long ling $也只有 1 e 18 1e18 1e18,在计算大数类问题会超出限制
  • 本题给出两种代码,一种是python,一种是c++
  • 有要备考蓝桥杯的同学要学会c++,因为c蓝桥杯是根据语言报的
python 代码
a=input()
b=input()
a=int(a)
b=int(b)
print(a+b)

  • 没错,python就是这么简单,五行代码结束,因为在python中,是没有数据大小这个限制的,所以直接可以采用常规的 a + b a+b a+b提交即可
c++代码
#include<bits/stdc++.h>
using namespace  std;
vector<int >add(vector<int>&A,vector<int>&B)
{
    if(A.size()<B.size())
        return add(B,A);
    vector<int>C;
    int t=0;
    for(int i=0;i<A.size();i++)
    {
        t+=A[i];
        if(i<B.size())
            t+=B[i];
        C.push_back(t%10);
        t/=10;
    }
    if(t)
        C.push_back(t);
    return C;
}
int main()
{
    string a,b;
    vector<int>A,B;
    cin>>a>>b;
    for(int i=a.size()-1;i>=0;i--)
        A.push_back(a[i]-'0');
    for(int i=b.size()-1;i>=0;i--)
        B.push_back(b[i]-'0');
    auto C=add(A,B);
    for(int i=C.size()-1;i>=0;i--)
        cout<<C[i];
    cout<<endl;


}
  • c++直接采用 v e c t o r vector vector对于上面给出的两个语法规则 v e c t o r vector vector a u t o auto auto不懂的自己百度,这里不做解释
  • a+b这种题都写过好多次了,不会还有人不会吧

C

  1. 暴力解法

这个暴力解法还是蛮好想的。

对于每个询问,从头到尾搜一遍,找到就输出并 b r e a k break break ,如果一直找不到最后输出 − 1 -1 1

然而这个的时间复杂度是 O ( n m ) O(nm) O(nm),显然过不了。

  1. 二分
  • 第一种方法,直接手搓二分
#include<bits/stdc++.h>
using namespace std;
int n,m,q,a[1000005];
int find(int x)
	{int l=1,r=n;
	while (l<r)
	{
		int mid=l+(r-l)/2;
		if (a[mid]>=x) r=mid;
		else l=mid+1;
	}

	if (a[l]==x) return l;
	else return -1;
}

int main()
{
	cin>>n>>m;

	for (int i=1 ; i<=n ; i++)
	    scanf("%d",&a[i]);

	for (int i=1 ; i<=m ; i++)
	{
		cin>>q;
		int ans=find(q);
		cout<<ans<<" ";
	}

	return 0;
}
  • 第二种方法,采用 s t l stl stl
  • 下面介绍一下这个函数
  • lower_bound(start, end, target):
  • 从在 s t a r t start start e n d end end区间内查找 t a r g e t target target,如果找到了,返回一个指针,如果没找到,返回第一个比它大的值的指针。
#include <iostream>
#include <vector>
using namespace std;
vector<int > vec;
int main() {
	int n, m;
	int t;
	cin >> n >> m;
	int index;
	while(n--) cin >> t, vec.push_back(t);
	while(m--) {
		cin >> t;
        // 在序列里查找目标数据
		index = lower_bound(vec.begin(), vec.end(), t) - vec.begin();
        // 如果目标数据找到了,输出答案,注意我们的数组下标是从0开始的
		if (t == vec[index]) 
        cout << index + 1 << ' ';
		else cout << -1 << ' ';
	}
	return 0;
}

D

  • 读题正常模拟就好了,easy的一道题目
  • 思路:只需要 L L L出现在 R R R之后即可
  • 也就是说只要有 R L RL RL即可
  • 如果没有就需要修改
  • 直接贴了当时比赛时候的代码,头文件的一堆可以忽略
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x)&-(x))
#define endl '\n'
#define int long long
const int INF=0x3f3f3f3f;
using ll=long long;
using ld=long double;
#define PB push_back
#define MK make_pair
#define EB emplace_back
#define rep(i,n,m) for(int i=n;i<=m;i++)
#define rrep(i,n,m) for(ll i = (ll)(m) - 1; i >= (ll)(n); i--)
const int N=10000010;
const int M=1010;
int tree[N];
int input[N];
#define lowbit(x) ((x)&(-x))
int solve()
{
   int n;
   cin>>n;
   string s;
   cin>>s;
   int ans=0;
   int sum=0;
   int flag=false;
   int kk=0;
   for(int i=0;i<n;i++)
   {
       if(s[i]=='L')
           ans++;
       else
           sum++;
       if(s[i]=='R'&&s[i+1]=='L')
           flag=true;
       else if(s[i]=='L'&&s[i+1]=='R')
           kk=i;
   }
   if(sum==n||ans==n)
       cout<<-1<<endl;
   else if(flag==true)
       cout<<0<<endl;
   else
   {
       cout<<kk+1<<endl;
   }

}
signed  main()
{
   ios::sync_with_stdio(false);
   cin.tie(0);
   cout.tie(0);
   int t;
   cin>>t;
   while(t--)
   {
       solve();
   }
  // solve();

}

E

  • 这到题目也是简单模拟
  • 这个代码是我刚刚学的时候写的,当时用正常的写法一直 T L E TLE TLE,一气之下直接果断打表,后来才发现,这道题数据有点下问题,如果暴力的话到了当运行到 9989899 9989899 9989899 T L E TLE TLE
  • 先说说打表的方法,直接找就行
#include<bits/stdc++.h>
 using namespace std;
 bool isPrime(int l){
    for(int i = 2; i*i <=l; i++){
        if (l % i == 0) {
            return false;
        }
    }
    return true;
}
  bool huiwen(int x) 
  {
        
        int t = x,c = 0;
        while(t>0)
        {
            c = c*10 + t%10;
            t /= 10;
        }
        return c == x;
    }
int getlength(int x)
{
    int m = 1, k = x;
    while(k > 9){
        k /= 10;
        m++;
    }
    return m;
    
}
int main(){
    int a, b;
    cin >> a >> b;
    int p, q;
    p = getlength(a);
    q = getlength(b);
    if(p <= 1 && q >=1){//一位
        if(a <= 5 && b>=5){
            cout << 5 << endl;
        }
        if(a <= 7 && b >= 7){
            cout << 7 << endl;
        }
    }
 
    if(p <= 2 && q >=2){//二位
        if(a <= 11 && b >= 11){
            cout << 11 << endl;
        }
    }
 
    if(p <= 3 && q >= 3){//三位
        int x,y;
        int temp;
        for(x = 1; x <= 9; x += 2){
            for(y = 0; y <= 9; y++){
                temp = x*100 + y*10 + x;
                if(temp >= a && temp <= b){
                    if(isPrime(temp)){
                        cout<<temp<<endl;
                    }
                }
            }
        }
    }
 
    if(p <= 5 && q >= 5){//五位
        int x,y,z;
        int temp;
        for(x = 1; x <= 9; x += 2){
            for(y = 0; y <= 9; y++){
                for(z = 0; z <= 9; z++){
                    temp = x*10000 + y*1000+ z*100 + y*10 +x;
                    if(temp >= a && temp <= b){
                        if(isPrime(temp)){
                            cout<<temp<<endl;
                        }
                    }
                }
            }
        }
    }
 
     if(p <= 7 && q >= 7){//七位
        int x,y,z,t;
        int temp;
        for(x = 1; x <= 9; x += 2){
            for(y = 0; y <= 9; y++){
                for(z = 0; z <= 9; z++){
                    for(t = 0; t <= 9; t++){
                        temp = x*1000000 + y*100000 + z*10000 + t*1000 + z*100 + y*10 + x;
                        if(temp >= a && temp <= b){
                            if(isPrime(temp)){
                                cout<<temp<<endl;
                            }
                        }
                    }
                }
            }
        }
    }
}
  • 那么如果不打表呢,该咋写
  • 还是想要暴力去写的话,卡数据就行
  • 这个代码是贴的,本人懒得写了(不建议效仿)
  • 没有测试数据你一辈子都不知道为什么会 w a wa wa,所以还是建议打表
  • 没错就是这么坑!!!
#include<iostream>
#include<cmath>
using namespace std;
int prime(int n) {
	if(n==1)//特判1 
		return 0;
	if(n%2==0) 
		return 0;
	else {
		int i;
		for(i=2; i<=sqrt(n); i++) {
			if(n%i==0)
				return 0;
		}
		return 1;
	}
}
int hw(int n) {
	int sum=0;
	int k=n;
	while(n!=0) {
		sum=sum*10+n%10;
		n/=10;
	}
	if(sum==k)
		return 1;
	else
		return 0;
}
int main() {
	int i,n,sum=0,m;
	cin>>n>>m; 
	for(i=n; i<=m; i++) {
		if(i==9989900) //如果到了这个数,就break ,就是卡在这里TLE了
			break;
		if(hw(i)&&prime(i))
			cout<<i<<endl;
	}
	return 0;
}
  • 然后,不知道细心的有没有发现,原来啊,偶数是不可能的!!!
  • 所以,我们只需要特判一下偶数即可,此时在没有数据的情况下也能正常 A C AC AC不会 T L E TLE TLE
  • 代码就不给出来了,稍加修改一下即可!

F

  • dp题

  • 核心思路

b[i]=max(a[i],b[i-1]+a[i]);
  • 本来是想出一道前缀和的题目,但是没注意把题目选错了,出成一道dp题
  • 但是,但是,但是!!! 重要的事情说三遍,这道题也可以用前缀和的思想来写

(亡羊补牢,这道题我没有出错!)

解法1,dp
#include<bits/stdc++.h>
using namespace std;
int a[200020], b[200020], n, i, ans = -0x3f3f3f;
int main()
{
	cin >> n;
	for (i = 1; i <= n; i++)
	{cin >> a[i];
	if (i < 2)
		b[i] = a[i];
	else b[i] = max(a[i], b[i - 1] + a[i]);
	ans = max(ans, b[i]);
}
	cout << ans;
	return 0;
}
解法2
  • 简单的递推,推下去就是了
  • 好吧,其实也没有用到,就是一个思想罢了
#include<iostream>
int main()
{
    using namespace std;
    int a,b=0;
    int n,sum=-100001;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>a;  //不用判断取不取数,反正这个数必须取,不取这个数就串不下去,重开串了
        if(b>0)
        b+=a;//如果前面的串比较大,就继续叠加下去,如果前面的串还不如0大
        else
        b=a;       //就重开一串
        if(b>sum) 
        sum=b;//保存最大值
    }
    cout<<sum;
    return 0;
}

G

  • 这这道题也是cf的一道题
  • 首先偶数应该怎么办大家肯定都知道, 1 − 1 1 -1 11这种交错排列使得结果是 0 0 0就行
  • 那么奇数应该咋整呢??
  • 如果你认为。奇数是不可能的,那么你就错了
  • 没错,我相信很多人都会觉得奇数是不可能的,那么请思考一下这个智慧数据
1 -2 1 -2 1
  • 没错,神奇的事情发生了
  • 奇数是可以的,结果为 − 1 -1 1
  • s o so so,根据这个案例,我们来模拟一下数据
1 -2 1 -2 1
2 -3 2 -3 2 -3 2
3 -4 3 -4 3 -4 3 -4 3 
  • 看到这里应该有思路了吧,没错,如果是奇数就不断交错排列即可
  • 那么下面给出代码(也是当时比赛时候写的,直接贴了,请忽略一些头文件)
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x)&-(x))
#define endl '\n'
#define int long long
const int INF=0x3f3f3f3f;
using ll=long long;
using ld=long double;
#define PB push_back
#define MK make_pair
#define EB emplace_back
#define rep(i,n,m) for(int i=n;i<=m;i++)
#define rrep(i,n,m) for(ll i = (ll)(m) - 1; i >= (ll)(n); i--)
const int N=10000010;
const int M=1010;
int a[N];
#define lowbit(x) ((x)&(-x))
int solve()
{
    int n;
    cin>>n;
    int kk=1;
    int pp=-1;
    if(n%2==0)
    {
        cout<<"YES"<<endl;
        for(int i=1;i<=n;i+=2)
        {
            a[i]=kk;
        }
        for(int i=2;i<=n;i+=2)
        {
            a[i]=pp;
        }
        for(int i=1;i<=n;i++)
        {
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }
    else if(n==1)
    {
        cout<<"YES"<<endl;
        cout<<1<<endl;
    }
    else if(n%2==1&&n!=3)
    {
        cout<<"YES"<<endl;
        int kk=(n-5)/2+1;
        int pp=kk-kk-kk-1;
        for(int i=1;i<=n;i+=2)
        {
            a[i]=kk;
        }
        for(int i=2;i<=n;i+=2)
        {
            a[i]=pp;
        }
        for(int i=1;i<=n;i++)
        {
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }
    if(n==3)
    {
        cout<<"NO"<<endl;
    }
}
signed  main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        solve();
    }
   // solve();

}
 

G

  • 这个题是真签到题了
  • 直接模拟,高中公式即可
  • 不做任何解释

#include<bits/stdc++.h>
using namespace std;
int main()
{
	double  x1,x2,y1,y2,x3,y3;
	 cin>>x1>>y1>>x2>>y2>>x3>>y3;
    double s=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))+sqrt((x2-x3)*(x2-x3)+(y2-y3)*(y2-y3))+sqrt((x1-x3)*(x1-x3)+(y1-y3)*(y1-y3));//求周长
    printf("%.2lf",s);
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值