河南萌新联赛2024第(二)场:南阳理工学院(部分题解)

题目D: A*BBBB

题目链接

题意描述:

t组输入,每组输入两个整数a,b,其中b的每位数字都相等,a,b非常大,0<=a,b<=101000000 ,并且a,b都不含前导0.

解题思路:

当一个数乘111时我们可以发现这个结果与每一位有关。当a=114514,b=111时:

请添加图片描述
当前数位小于等于b的数位时,相加即为当前数位的结果,当前数位大于b的数位时,依次去除前一位数字,直到只剩最后以为数字计算后结束。
因此我们在计算时,可以将b拆分为a111…,例如33333可以拆分为x=3与、y=11111
然后将a
x用高精求出结果,再将结果与y进行规律的计算,最终可找出答案

代码:

#include<bits/stdc++.h>
using namespace std;
int sum[1000010]={0};
signed main()
{
	int t;
	cin>>t;
	while(t--)
	{   
		memset(sum,0,sizeof(sum));
		string s1,s2;
		cin>>s1>>s2;
		reverse(begin(s1),end(s1));
		int a=0,b,c=s2[0]-'0';
		vector<int>res;
		for(int i=0;i<s1.size();i++)
		{
			b=(s1[i]-'0')*c;
			res.push_back((b+a)%10);
			a=(b+a)/10;
		}
		while(a)
		{
			res.push_back(a%10);
			a/=10;
		}
		int n=res.size();
		for(int i=0;i<res.size();i++)
		sum[i+1]=sum[i]+res[i];
		string ans;
		int q=0;
		for(int i=1;i<=n+s2.size();i++)
		{
			int l=max(0,(int)(i-s2.size()));
			int r=min(i,n);
			q+=sum[r]-sum[l];
			ans.push_back(q%10+'0');
			q=q/10;
		}
		while(q)
		{
			ans.push_back(q%10+'0');
			q/=10;
		}
		while(ans.size()>1&&ans.back()=='0')
		ans.pop_back();
		reverse(ans.begin(),ans.end());
		cout<<ans<<endl;
	}
}

H 狼狼的备忘录

题目链接

题意:

输入备忘录的本数,每本包含成员名字,以及信息数,接下来是每条信息,信息是长度不超过10的非空字符串,你需要将同一成员的汇集在一起,如果信息a的后缀与完整信息b相同,则删除信息b,最后把名字按字典序排列,然后输出名字,信息数,信息即可

解题思路:

用容器map<string,set >mp 存储,这样名字就可以自动排序,然后当查找信息后缀是否与别的完整信息重复时,由于信息存在了set中,可以用count是否为真判断,信息后缀的截取可以用substr函数

解题代码:

#include<bits/stdc++.h>
using namespace std;
map<string,set<string> >mp;
int main()
{
	int n;
	cin>>n;
	while(n--)
	{
		string s;
		int m;
		cin>>s>>m; 
		for(int i=1;i<=m;i++)
		{
			string p;
			cin>>p;
			mp[s].insert(p);
		}
	}
	for(auto &&[x,y]:mp)
	{
		for(auto &&s:y)
		{
			for(int i=1;i<s.size();i++)
			{
				string str=s.substr(i);
				if(y.count(str))
				y.erase(str);
			}
		}
	}
	cout<<mp.size()<<endl;
	for(auto &&[x,y]:mp)
	{
		cout<<x<<" ";
		cout<<y.size()<<" ";
		for(auto &&s:y)
		cout<<s<<" ";
		cout<<endl; 
	}
	return 0;
}

J 这是签到

题目链接

题意描述

有一个n*m的行列式,如果n!=m,则行列式无法计算,我们补充行或列为0,使其变为可以计算的,然后计算出可计算的行列式的最小值

解题思路:

这道题,我用的暴力,数据范围比较小,就列举出来了。
在最初,我是想先把行列式进行补充,使得m=n,然后进行计算,后来听学长讲后发现,如果m!=n,结果为0,只需要在最后的进行下列操作即可

int k=0;
mi=min(k,min);

在行列中当1,2*2,都比较易于计算,当大于等于3时,将原理啊的行列式在右边再写一遍,当把其遍历1遍就停止。请添加图片描述结果即为行列式的结果.

代码:

#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
int a[10][10];
signed main()
{
	IOS
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		cin>>a[i][j];
	} 
// 	if(m>n)
// 	for(int i=n+1;i<=m;i++)
// 	{
// 		for(int j=1;j<=m;j++)
// 		a[i][j]=0;
// 	}
// 	if(m<n)
// 	for(int i=1;i<=n;i++)
// 	{
// 		for(int j=m+1;j<=n;j++)
// 		a[i][j]=0;
// 	}
	int x=min(n,m);
	int mi=INT_MAX;
	int p=0;
	if(x>=1)
	{
		p=a[1][1];
		mi=min(mi,p);
	}
	if(x>=2)
	{
		p=(a[1][1]*a[2][2]-a[2][1]*a[1][2]);
		mi=min(mi,p);
	}
	if(x>=3)
	{
		p=((a[1][1]*a[2][2]-a[2][1]*a[1][2])*a[3][3])+((a[1][2]*a[2][3]-a[1][3]*a[2][2])*a[3][1])+((a[1][3]*a[2][1]-a[1][1]*a[2][3])*a[3][2]);
		mi=min(mi,p);
	}
	if(x>=4)
	{
		p=(a[1][1]*a[2][2]*a[3][3]-a[1][3]*a[2][2]*a[3][1])*a[4][4]+(a[1][2]*a[2][3]*a[3][4]-a[1][4]*a[2][3]*a[3][2])*a[4][1]+(a[1][3]*a[2][4]*a[3][1]-a[1][1]*a[2][4]*a[3][3])*a[4][2]+(a[1][4]*a[2][1]*a[3][2]-a[1][2]*a[2][1]*a[3][4])*a[4][3];
		mi=min(mi,p);
	}
	if(x>=5)
	{
		p=(a[1][1]*a[2][2]*a[3][3]*a[4][4]-a[1][4]*a[2][3]*a[3][2]*a[4][1])*a[5][5]+(a[1][2]*a[2][3]*a[3][4]*a[4][5]-a[1][5]*a[2][4]*a[3][3]*a[4][2])*a[5][1]+(a[1][3]*a[2][4]*a[3][5]*a[4][1]-a[1][1]*a[2][5]*a[3][4]*a[4][3])*a[5][2]+(a[1][4]*a[2][5]*a[3][1]*a[4][2]-a[1][2]*a[2][1]*a[3][5]*a[4][4])*a[5][3]+(a[1][5]*a[2][1]*a[3][2]*a[4][3]-a[1][3]*a[2][2]*a[3][1]*a[4][5])*a[5][4];
		mi=min(mi,p);
	}
    int w=0;
    if(m!=n)
    mi=min(mi,w);
	cout<<mi<<endl;
	return 0;
}
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值