P - Submarine in the Rybinsk Sea (easy edition)(数论思想+规律)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这道题挺有意思的;如果够聪明的话直接可以大概猜出来结果;但是我没那么聪明,嘻嘻;
这道题一看两个连加符号:在这里插入图片描述
然后n又是1e5,然后nn肯定就爆了,所以枚举肯定不行,所以只有走找规律的这条路了;
根据他的f函数定义,可以知道这个结论:
在这里插入图片描述
为什么有这个东东呢?
可以这样想,因为每次a1都会遍历所有的aj,a2也同理…an也同理;我可以这样想:有点像错位相加的感觉(因为这个每个数的长度相等):
在这里插入图片描述
那么就有:
在这里插入图片描述
是不是就相当于,把111变成111111,222变成222222,意思就是每个数字重复两次相加;
所以可以得到上面的结论;
但是怎么把两个连加符号写成一个呢?
可以这样理解:
在这里插入图片描述
当a1枚举到a2的时候,是不是当a2的时候就会枚举到a1去(绿色的那根)?;
所以根据上面的推论公式可以知道:
在这里插入图片描述
以这个规律下去,可以发现:在这里插入图片描述
出现了n次,同理f(an,an)也会出现n次,所以总得和就是所有的相加
n;
注意:在算重复数字的时候需要取Mod(因为有Mod的性质可以知道)
AC代码:

#include<bits/stdc++.h>
using namespace std;
#define Mod 998244353
#define M 100050 
typedef long long ll;
ll F(ll a){
	  ll t=a,tt=a;
	  ll num=0;
	  while(tt){
	  	  num++;//算位数
	  	  tt/=10;
	  }
	  ll temp[20];//因为最多才20位;
	  ll i=0;
	  for(int j=0;j<num;j++){
	  	    temp[i++]=t%10;
	  	    temp[i++]=t%10;
	  	    t/=10;
	  }
	  ll res=0;//算结果
	  for(int k=2*num-1;k>=0;k--){
	  	  res=res*10+temp[k];
	  	  res%=Mod;//注意这里需要取模(因为我平常没怎么用过这种性质(只是常用+ - * /的Mod的性质))
	  }
	  return res%Mod;
}
int main(){
	ll n,a[M];
	scanf("%lld",&n);
	for(int i=0;i<n;i++)scanf("%lld",a+i);
	ll ans=0;
	for(int i=0;i<n;i++){
		   ans=(ans+F(a[i]))%Mod;
		  // cout<<F(a[i])<<endl;
	}
	printf("%lld\n",ans*n%Mod);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值