视频题解: www.bilibili.com/video/BV1ai…
A - Sanitize Hands (atcoder.jp)
思想
这道题是求最长前缀
前x个前缀和如果大于m了,那么就不再向后累加了,输出此时的前缀即可.
B - Uppercase and Lowercase (atcoder.jp)
思想
第二个题是个签到题,一次过:
#include<bits/stdc++.h>
using namespace std;
int cnt1,cnt2;
int main()
{
string s;cin>>s;
for(int i=0;i<s.size();i++)
{
if(islower(s[i]))
{
cnt1++;
}
else cnt2++;
}
if(cnt1>cnt2)
{
for(int i=0;i<s.size();i++)
{
s[i]=tolower(s[i]);
}
}
else
{
for(int i=0;i<s.size();i++)
{
s[i]=toupper(s[i]);
}
}
cout<<s<<endl;
return 0;
}
C - Sierpinski carpet (atcoder.jp)
题意解析
题目的意思是说 当前等级网格的每一个网格块都是由9个上一等级网格构成的.
例如下图左边是一等级网格,右边是二等级网格. 二等级网格的每一个网格块都是由一等级网格构成的:
二等级网格是由9个一等级网格的网格块组成的,其中八个一等级网格块构成了二等级网格的外围,二等级网格中间部分全部填充为'.'
解题思想
因为N的数据范围很小,所以可以模拟做:
#include<bits/stdc++.h>
using namespace std;
const int N=1000,M=200005;
char s[N][N];
char a[10];
int n;
void dfs(int u,int x,int y)
{
if(u==0) return;
int d=a[u-1];
for(int i=x+d;i<x+2*d;i++)
for(int j=y+d;j<y+2*d;j++)
s[i][j]='.';
//剩下的八层递归下去
for(int i=0;i<3;i++)
{
for(int j=1;j<3;j++)
{
if(i==1&&j==1)continue;
dfs(u-1,x+i*d,y+j*d);
}
}
}
int main()
{
cin.tie(nullptr)->sync_with_stdio(0);
a[0]=1;
for(int i=1;i<=6;i++) a[i]=a[i-1]*3;
cin>>n;
int w=a[n]; //边长
//先把矩阵全部初始化为'#'
for(int i=0;i<w;i++)
{
for(int j=0;j<w;j++)
{
s[i][j]='#';
}
}
dfs(n,0,0); //n表示n层 (0,0)代表左上角
for(int i=0;i<w;i++) puts(s[i]);
return 0;
}
D - 88888888 (atcoder.jp)
这道题让我们求n个n拼接 % MOD的结果
但是注意n特别大
那么首先我们要算出n个n拼接之后的数.拿当n==5时举例,它的拼接方法如下:
我们可以用公式表示为:
我们注意这是一个等比数列,我们可以用等比数列求和公式求出结果:
为了方便计算,我们把公式做了变化:
然后就可以计算了, 因为:
把公比,代入,得:
这样我们就计算出来了x,最后我们1还要对x取模,那么就变为:
code
分子分母的单独计算都用快速幂去求,分子/分母通过逆元转化为分子*分母的逆元
整体代码如下:
再单独看看最重要的计算那部分: