2021辽宁省大学生程序设计竞赛(正式赛)F、G、L、E

这篇博客主要探讨了C/C++编程中的算法和数据结构应用。涉及了排列组合问题、字符串转换、模拟及字节类型的处理。文章通过实例解析了如何解决复杂计算问题,包括使用动态规划和数组维护最大值和最小值。同时,提到了在处理大整数时需要注意的数据类型溢出问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

F、Capslock

任意门

#include<iostream>
#include<cstring>
#include<math.h>
#include<map>
#include<algorithm>
#define PI acos(-1)
using namespace std;

int main()
{
    bool flag=0;
    string s;
    cin>>s;
    for(int i=1;i<s.size();i++)
        if(s[i]>'Z')//就是小写字母
        flag=1;
    if(flag==0)
    {
        if(s[0]>'Z')
            s[0]-='a'-'A';
        else s[0]+='a'-'A';
        for(int i=1;i<s.size();i++)
        s[i]+='a'-'A';
        cout<<s<<endl;
    }
    else cout<<s<<endl;
    return 0;
}

G、字节类型

任意门

 这里get到了一个新用法,就是__int128,这个东西不能直接读入和输出,目前你只能用String类型来读入,然后再传到__int128类型里面。你可以直接拿它和其他的数来比较,但是不能直接输出;

 

 

 

还有一点要注意的是,题目已经说了他是正数,所以只用比较他们正数的部分就可以了。

#include<bits/stdc++.h>
using namespace std;
string a;
__int128 x=0;
int main()
{
	cin>>a;
	int len=a.size();
	if(len>=20){
		printf("BigInteger\n");
		return 0;
	}
	for(int i=0;i<len;i++){
		x=x*10+a[i]-'0';
	}
	if(x>9223372036854775807)printf("BigInteger\n");
	else if(x>147483647)printf("long\n");
	else if(x>32767)printf("int\n");
	else if(x>127)printf("short\n");
	else printf("byte\n");
	return 0;
}

 

L、神奇的回答

任意门

这是一道简单的签到题!

#include<bits/stdc++.h>
using namespace std;


int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int a;
        cin>>a;
        if(a>=18)
            cout<<"18"<<endl;
        else cout<<a<<endl;
    }
	return 0;
}

E、生活大爆炸

任意门

这一题就是高中数学的排列组合,这一题我一开始就是把他的数学式子列出来,然后化为最简式,然后就可以发现其实就是几个阶层相除,但是这样子的话,好不容易用unsigned long long 把他给表示出来了,但是你要是再用除法的话,那样子肯定会emmm,反正我是没有输出结果的。所以这里就是用dp来,就是初始化dp数组,这里只要找到它的规律,那么一切好说。这里就是a[i][j]=a[i-1][j-1]+a[i-1][j],就是再来一个人,这个人可能被选中,也可能被被选中,然后把他的每一种情况相加,那么就保证的是从i+1个人里面选取j个人,然后这个新增的这个人可以选,也可以不选。

#include<bits/stdc++.h>
using namespace std;

const int N=65;
int n,m;
int a[N][N];//他的意思是从i个人里面选取j个人

void f()
{
    for(int i=0; i<N; i++)
        for(int j=0; j<N; j++)
        {
            if(!j)//就是选取0人就是
                a[i][j]=1;
            else a[i][j]=a[i-1][j-1]+a[i-1][j];//再加一个人,可以被选取,也可不被选取    }
        }
}
int main()
{
    ios::sync_with_stdio(false);
    f();
    cin.tie(0);
    int n,m,t;
    cin>>n>>m>>t;
    long long ans=0;
    for(int i=4; i<=n; i++)
        for(int j=1; j<=m; j++)
            if(i+j==t)
                ans+=a[n][i]*a[m][j];
    cout<<ans<<endl;
    return 0;
}

后来看到了别人用排列组合的做法写出来了,后来才发现,自己不应该简化的,也不许构造数组。

 

#include<bits/stdc++.h>
#define ll __int128
using namespace std;
int n,m,t;
ll c(ll x,ll y){
	if(y>x/2)y=x-y;
	ll ret=1;
	for(ll i=x;i>=x-y+1;i--)ret*=i;
	for(ll i=1;i<=y;i++)ret/=i;
	return ret;
}
int main()
{	
	cin>>n>>m>>t;
	ll ans=0;
	for(ll i=4;i<=min(n,t-1);i++){
		if(t-i>m||t-i<1) continue;
		ans+=c(n,i)*c(m,t-i);
	}
	int an[10000],cnt=0;
	while(ans){
		an[++cnt]=ans%10;
		ans/=10;
	}
	for(int i=cnt;i>=1;i--){
		printf("%d",an[i]);
	}
	return 0;
}

D、阿强与网格

任意门

纯模拟题。

wa的原因是n,m,x,y开的是int,开小了,我想着我ans开的long long 就没事了,但是他是10^5次方,然后相乘的话就会爆int,然后他就会变成随便的一个数,然后这个时候就要用long long来才可以。 学到了!get it!

#include<bits/stdc++.h>
using namespace std;

const int N=100010;

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        long long n,m,x,y;
        scanf("%lld%lld%lld%lld",&n,&m,&x,&y);
        long long ans=0;
         if(n<m)swap(n,m);
        if(m==1)
        {
             ans=(n-1)*x;
            printf("%lld\n",ans);
             continue;
        }
        if(y>=2*x)
            ans=(n+m-2)*x;
            else if(y>=x)
                ans=(n-m)*x+(m-1)*y;
       else
        {
            if((n-m)%2==0)
               ans=y*(n-1);
            else ans=y*(n-2)+x;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

C、传染病统计

模拟题!先排序,然后把相邻的两个的判断是否距离小于等于2,然后记录一下,从前往后遍历,然后,用cnt来记录一下这一段的长度,然后用这个cnt来维护最大值和最小值。

#include<bits/stdc++.h>
using namespace std;

const int N=15;

int a[N],b[N];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        sort(a+1,a+n+1);
        b[n]=n;
        for(int i=1;i<n;i++)
          if(a[i+1]-a[i]<=2)b[i]=i+1;
          else b[i]=i;
          int ans=0,mx=0,mn=110;
          for(int i=1;i<=n;i++)
          {
              ans++;
              //cout<<b[i]<<" ";
              if(b[i]==i+1)continue;
              else {
                mx=max(mx,ans);
                mn=min(mn,ans);
                ans=0;
              }
          }
          memset(b,0,4*n);
          printf("%d %d\n",mn,mx);
    }
    return 0;
}


还有线段树板子题II-完美主义_2021辽宁省大学生程序设计竞赛(正式赛)(重现赛)@JXNU_19_ACS (nowcoder.com)

dp题

J-放棋子_2021辽宁省大学生程序设计竞赛(正式赛)(重现赛)@JXNU_19_ACS (nowcoder.com)

待补!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值