AtCoder Beginner Contest 357

题目大意:有n个外星人和m个洗手剂,每个外星人有a【i】只手,一个洗手剂可以清洗一只手,按输入顺序清洗外星人,问可以一共完整清洗多少个外星人。

也就是将a变成前缀和数组,找到小于m的最大值。

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
int n,m,a[N];
int main()
{
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>a[i];
	int num=0;
	for(int i=1;i<=n;i++)
	{
		if(m>=a[i])
		{
			num++;
			m=m-a[i];
		}
		else break;
	}
	cout<<num<<endl;
}

题目大意:一个字符串长度为奇数且由大写字母和小写字母组成,如果大写字母数量比小写字母多就把这个字符串全部变成大写字母输出,反之变成小写字母输出

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
int n,m,a[N];
int main()
{
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	string str;
	cin>>str;
	n=str.size();
	int l=0,r=0;
	for(int i=0;i<n;i++)
	{
		if(str[i]>='a'&&str[i]<='z')l++;
		else r++;
	}
	if(l>r)
	{
		for(int i=0;i<n;i++)
		{
			if(str[i]>='A'&&str[i]<='Z')str[i]+=32;
			cout<<str[i];
		}
	}
	else 
	{
		for(int i=0;i<n;i++)
		{
			if(str[i]>='a'&&str[i]<='z')str[i]-=32;
			cout<<str[i];
		}
	}
}

题目大意:输入一个n,输出一个3^n行3^n列的图形,这个图形由九个部分组成,外围八个部分是由前一个3^(n-1)行3^(n-1)列的图形拼凑而成,中间那个部分则全部用‘.’组成。

例如输入1,则会生成

###
#.#
###
所以模拟一遍他每次生成的图形,a数组为(i-1)图形,b数组为(i)图形,每次都用a数组来生成b数组的新图形,然后把b数组重新赋值给a数组就行了。

0的时候只需要输出一个‘#’就行。

写的时候不知道为什么n范围看成10去了,3^10已经5e4了,数组开不出来,就没办法模拟,递归也不是很理解,就写D题去了,结果D题也没写出来还开了个unsigned long long导致C题一直RE。

不过这题递归应该更正确一点,数组模拟有点太复杂了。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=3000+10;
const int MOD=998244353;
int n,m;
char a[N][N],b[N][N];
signed main()
{
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin>>n;
	for(int i=1;i<=3;i++)a[1][i]='#',a[3][i]='#';
	a[2][1]='#';a[2][2]='.';a[2][3]='#';
	m=3;
	if(n==0)
	{
		cout<<"#"<<endl;
		return 0;
	}
	for(int i=1;i<=n-1;i++)
	{
		int t=m;
		m=m*3;
		for(int j=1;j<=m;j++)
		{
			int num=0;
			if((j-1)/t==0)
			{
				for(int p=1;p<=3;p++)
				{
					for(int l=1;l<=t;l++)
					{
						num++;
						b[j][num]=a[j][l];
					}
				}
			}
			else if((j-1)/t==1)
			{
				for(int l=1;l<=t;l++)
				{
					num++;
					b[j][num]=a[(j-1)%t+1][l];
				}
				for(int l=1;l<=t;l++)
				{
					num++;
					b[j][num]='.';
				}
				for(int l=1;l<=t;l++)
				{
					num++;
					b[j][num]=a[(j-1)%t+1][l];
				}
			}
			else 
			{
				for(int p=1;p<=3;p++)
				{
					for(int l=1;l<=t;l++)
					{
						num++;
						b[j][num]=a[(j-1)%t+1][l];
					}
				}
			}
		}
		for(int j=1;j<=m;j++)
		{
			for(int p=1;p<=m;p++)a[j][p]=b[j][p];
		}
	}
	for(int j=1;j<=m;j++)
	{
		for(int p=1;p<=m;p++)cout<<a[j][p];
		cout<<endl;
	}
}

题目大意:输入一个N,用N个N组成一个新数字去模998244353。例如输入一个5,就用5个5组成55555然后模998244353,所以输出55555。

N范围是1e18,当时没看到范围还以为开个高精度除法就过了,结果写完看到第三个案例怎么这么大,然后才发现N有1e18。

首先,直接走一遍最起码也要1e18,这个数字只能用log(n)的方法去写,或者说有个结论。

我们能发现9,90,900,9000......900000000这些数字有个共同特点,那就是等比数列,由N个N组成的数字就是9+90+900+......+900000000,这就是等比数列的求和。

等比数列的求和公式:a【1】*(1-q^n)/(1-q),a【1】就是n本身,那么q是什么,能发现每次N往前堆的时候都会增加N字符数量的长度,比如9每次都会多一个0,也就是10^1,10每次都会多两个0,也就是10^2,所以这个等比公式就能写出来了。

除法可以用逆元来解决:除x可以变成乘x^(MOD-2)。

用一个快速幂就能解决所有算式了。

等比数列居然完全没有看出来QAQ。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int MOD=998244353;
const int N=1e3+10;
int n,len;
int qpow(int x,int k)
{
	int res=1;
	while(k>0)
	{
		if(k%2)res=(res*x)%MOD;
		x=(x*x)%MOD;
		k=k/2;
	}
	return res;
}
signed main()
{
	cin>>n;
	int t=n;
	while(t!=0)
	{
		len++;
		t=t/10;
	}
	cout<<(n%MOD*(qpow(qpow(10,len),n)-1)%MOD*(qpow(qpow(10,len)-1,MOD-2)))%MOD<<endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值