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

比赛链接

D A*BBBB

每组输入给两个整数aa和bb,输出a∗b。但是a,b非常大,0<=a,b<=1000000。其中b的每一位都相同,且a,b都不含前导0。

思路

这题就是一个高精算数,特殊点是b每一位都相同,所以我起初想的就是:

先高精乘个位数,在错位进行高精加。

今天看了其他人的代码,我的思路就显得中规中矩,毫无技巧,完全不动脑子的模拟,下面这个代码的思路:
将a中会影响 积 中某一位的加一块,乘 b[0] , 再对10取模,放进字符串。
就比如下面这张图
请添加图片描述
影响第一位的,只有5,影响第二位的,是 4,5,影响第三位的,是3,4,5。为什么可以直接(4+5)*3,其实一想,就是个分配律。(当然,这里我没加进位部分)
所以在代码中,用sum在for循环中累加,因为b.size()=3,所以只有三行相加,当位数 i>=b.size()时,sum- =a[i-b.size()]。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
   int t;
   cin >> t;
   while(t--) {
       string a, b, ans;
       cin >> a >> b;
       reverse(a.begin(),a.end());
       int x=b[0]-'0';
       int jin=0,sum=0;
       for(int i=0;i<a.size()+b.size();i++)
       {
           if(i<a.size())
           sum+=a[i]-'0';
           if(i>=b.size())
           sum-=a[i-b.size()]-'0';
           jin+=sum*x;
           ans+=jin%10+'0';
           jin/=10;
       }
       while(ans.back()=='0'&&ans.size()>1)
       ans.pop_back();
       reverse(ans.begin(),ans.end());
       cout<<ans<<'\n';
   }
}

string还可以pop_back,push_back;

H 狼狼的备忘录

思路

就是一道纯模拟。

  • 没审清题,前导零信息也字典序输出
    而我起初用数组存的,最后只能全改了,最后一个bug 就是,我糊涂的把不符合的设为0,致使0也无法输出。也算因祸得福,学长帮我下了个新编译器,还有一个"对拍",我真是太需要了。
    当然我的代码很复杂,长,没能巧妙地运用stl

代码

下面两个代码,第一个简洁,第二个毕竟是我的心血,也放上去了

#include "bits/stdc++.h"
using namespace std;
map<string,set<string> >mp;//set里边存信息,也不需要计数了
int main()//也可以直接字典序
{
    int n;
    cin>>n;
    string s;
    int m;
    for(int i=1;i<=n;i++)
    {
        cin>>s>>m;
        for(int j=1;j<=m;j++)
        {
            string ss;
            cin>>ss;
            mp[s].insert(ss);
        }
    }
    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()<<'\n';
    for(auto &&[x,y]:mp)
    {
        cout<<x<<" ";
        cout<<y.size()<<" ";
        for(auto &&s:y)
            cout<<s<<" ";
        cout<<'\n';
    }
}
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
typedef struct xing{
	string na;
	int m;
	string in[205]={"*"};
	int mn=0;
	string xxx;
}xing;
xing x[25];
signed main()
{
	map<string,int> ma;
	IOS
	int n;
	cin>>n;
	int i=0;
	for(int i=1;i<=n;i++)
	{
		string name;
		cin>>name;
		if(ma.count(name)!=0)
		{//去相同
			int f=ma[name],mm;
			cin>>mm;
			for(int ii=1;ii<=mm;ii++)
			cin>>x[f].in[++	x[f].m];
		}
		else
		{
		    x[i].na=name;
			ma[x[i].na]=i;
			cin>>x[i].m;
			for(int j=1;j<=x[i].m;j++)
			cin>>x[i].in[j];
		}
	}//去后缀
 	for(auto it:ma)
 	{ 
 		int t=x[it.second].m;
 		int i=it.second;
	 	for(int j=1;j<t;j++)
	 	for(int k=j+1;k<=t;k++)
	 	{
		 	string jj=x[i].in[j];
		 	string kk=x[i].in[k];
		 	if(jj!="*"&&kk!="*")
		 	{
		 		
			 	int cj=1,f=0;
			 	int xia=min(jj.size(),kk.size());
			 	int jjl=jj.size(),kkl=kk.size();
	 		 	for(int io=1;io<=xia;io++)
	 		 	{
	 		 		if(jj[jjl-io]!=kk[kkl-io])
	 		 		f=1;
	 			 }
	 			 if(f==0)
	 			 {
	 			 	if(jjl>kkl)
	 			 	x[i].in[k]="*";
	 			 	else
	 			 	x[i].in[j]="*";
	 			 	x[i].mn++;
				 			 }
			 }
		 }
	 }
	 string xx[250];
	 for(auto it:ma)
	 {
	 	int kk=0;
	 	int i=it.second;
	 	for(int j=1;j<=x[i].m;j++)
 		{
 			if(x[i].in[j]!="*")
 			 xx[kk++]=(x[i].in[j]);
 		}
 		sort(xx,xx+kk);
 		for(int j=0;j<kk;j++)
 		x[i].xxx+=xx[j]+" ";
	 }
	 		
	  
	 cout<<ma.size()<<'\n';
	for(auto it:ma)
	{
		cout<<it.first<<" ";
		int i=it.second;
		cout<<x[i].m-x[i].mn<<" ";
		cout<<x[i].xxx;
		cout<<'\n';
	}
}

J 这是签到

题目要求冰冰得到一个 n×m 的行列式。有些行列式可能无法直接计算,但可以做一个操作:在行或列补充全为 00 的一行或一列,使其变为可计算的。不过最多只能扩充成 max(n,m)×max(n,m) 的行列式。要想拿满分,需计算所有可计算行列式中从 (1,1) 位置构成的最小值

思路

这是一个数学中的行列式计算,我的第一反应就是,大不了暴力列式子。因为前几天刚看到(n* i+j),想用一维数组存,我列式子也方便,不过忽略了不同m,n,(ni+j)也就不同了,后来还是老实的用二维,我就开始列33,刚列完,嫌麻烦,就开始用循环写了。

既然是对角线,就是依次连续的向左乘的加一块,减去向右的。i,j 就必然存在某种关系,就拿正对角线说,第一条,i=j,第二条 i+1=j,第三条 i+2=j…当然这里还要加上取模
说实话,这样下来,还没暴力列式子,A得快。但再来一次,我还会这样。毕竟,赛后,估计我就不会再想用两个循环怎么弄。

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int a[100][100];
signed main()
{
  IOS
  int n,m,mi=0x3f3f3f3f,sum=0;
  cin>>n>>m;
  for(int i=1;i<=n;i++)
  for(int j=1;j<=m;j++)
  cin>>a[i][j];
  int xx=min(n,m),y=max(n,m);
	for(int x=1;x<=xx;x++)
	{
    	if(x==1)
    	mi=min(mi,a[1][1]);
    	if(x==2)	{
  	  	 sum=a[1][1]*a[2][2]-a[2][1]*a[1][2];
  	  	mi=min(mi,sum);
  	  }
     if(x>=3)
    {
          sum=0;
  	  int jian=0;
		    for(int j=1;j<=x;j++)
		    {
		    	int ch=1;
				for(int k=1;k<=x;k++)
			    {
					int yy=(k+j-1)%x;
			    	if(yy==0) yy=x;
					ch*=a[k][yy];
				}
				sum+=ch;
			}
		    for(int j=1;j<=x;j++)
		    {
		    	int yy=(j+1)%x+x,ch=1;
				for(int k=1;k<=x;k++)
			    {
					int yyy=(yy-k)%x;
			    	if(yyy==0) yyy=x;
					ch*=a[k][yyy];
				}
				jian+=ch;
			}
		    sum=sum-jian;
  	    mi=min(mi,sum);
      }
  	}
    if(m!=n)
    mi=min(mi,0ll);
    cout<<mi;
  
}

还有三道

I 重生之zbk要拿回属于他的一切
F 水灵灵的小学弟
A 国际旅行I
很水,就不加了

总结

审题不清,盲目开敲,模拟也应该想一下STL。

A少看一句话,差点和上周萌新K,犯同样错误了,不过上次题目描述有问题。这次真是自己漏看了。
比赛时间看错,致使后来比较匆忙。

全是借口理由罢了。。。。。。

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值