AtCoder ABC341 A-E题解

比赛链接:ABC341

Problem A:

先签个到。

#include <bits/stdc++.h>
using namespace std;
int main() {
  	int n;
  	cin>>n;
  	for(int i=0;i<n;i++)
    	cout<<"10"<<endl;
  	cout<<"1"<<endl;
  	return 0;
}

Problem B:

继续签。

#include <bits/stdc++.h>
using namespace std;
const int maxn=200005;
int a[maxn],s[maxn],t[maxn];
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
		cin>>a[i];
    for(int i=1;i<=n-1;i++)
		cin>>s[i]>>t[i];
    for(int i=1;i<=n-1;i++)
        a[i+1]+=a[i]/s[i]*t[i];
    cout<<a[n]<<endl;
    return 0;
}

Problem C:

水题,直接\Theta (n^3)模拟就行了。

#include <bits/stdc++.h>
using namespace std;
int n,m,k;
char grid[505][505];
bool valid(int x,int y){
    if(x>=1 && y>=1 && x<=n && y<=m && grid[x][y]!='#')
        return true;
    else
        return false;
}
int main(){
    cin>>n>>m>>k;
    string op;
    cin>>op;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)
            cin>>grid[i][j];
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(grid[i][j]=='#')
				continue;
            int x=i,y=j;
            bool ok=true;
            for(int l=0;l<k;l++){
                if(op[l]=='L')
					y--;
                else if(op[l]=='R')
					y++;
                else if(op[l]=='U')
					x--;
                else
					x++;
                if(valid(x,y)){//看清条件
                    ok=false;
                    break;
                }
            }
            if(ok)
				ans++;
        }
    }
    cout<<ans<<endl;
    return 0;
}

Problem D:

有意思的数学题。

我们知道,从1到lcm(n,m)中,只有\frac{lcm(n,m)}{n}个可以被n整除,同理,有\frac{lcm(n,m)}{m}个可以被m整除。

而从1到lcm(n,m)中,只有lcm(n,m)可以同时被n和m整除。

再换句话说,从1到lcm(n,m)中有\frac{lcm(n,m)}{m}-1个只能被n整除,同理,有\frac{lcm(n,m)}{n}-1可以被m整除,所以,从1到lcm(n,m)中,有\frac{lcm(n,m)}{n}+\frac{lcm(n,m)}{m}-2个符合条件的数。所以,在每个长度为lcm(n,m)的区间内,都有那么多个满足条件的数(实在懒得打LaTeX了)。

综上,答案就是在第\left \lceil \frac{k}{a} \right \rceil个区间第k mod a小的数。

#include <bits/stdc++.h>
using namespace std;
long long lcm(long long x,long long y){
	return x*y/__gcd(x,y);
}
long long count(long long x,long long y){
	return lcm(x,y)/x+lcm(x,y)/y-2;
}
int main(){
	long long n,m,k;
	cin>>n>>m>>k;
	long long ans=k/count(n,m)*lcm(n,m);
	k%=count(n,m);
	if(k==0){
		cout<<ans-min(n,m)<<endl;
		return 0;
	}
	long long p=1,q=1;
	while(--k){//为什么这里写成k--不行啊
		if(n*p<m*q)
			p++;
		else
			q++;
	}
	cout<<ans+min(n*p,m*q)<<endl;
	return 0;
}

顺便说一句,为什么19行不能写成k--啊,本蒟蒻调了半天,有知道的大佬可以在评论区告诉我,我将感激不尽。

Problem E:

我们定义一个数组f,用来看S_iS_{i+1}是否相等。这样,只要a_L+a_{L+1}+......+a_{R-1}=0,就输出YES。(注意,是加到a_{R-1}) 单点修改,区间查询,树状数组取之!(没必要用线段树)

#include <bits/stdc++.h>
using namespace std;
const int maxn=500005;
int c[maxn];
bool f[maxn];
char S[maxn];
int lowbit(int x){
	return x&(-x);
}
void modify(int x,int val){
	while(x<maxn){
		c[x]+=val;
		x+=lowbit(x);
	}
}
int query(int x){
	int res=0;
	while(x){
		res+=c[x];
		x-=lowbit(x);
	}
	return res;
}
int main() {
	int N,Q;
	cin>>N>>Q;
	for(int i=1;i<=N;i++)
		cin>>S[i];
	for(int i=2;i<=N;i++){
		if(S[i-1]==S[i]){
			modify(i-1,1);
			f[i-1]=true;
		}
	}
	while(Q--){
		int op,L,R;
		cin>>op>>L>>R;
		if(op==1){
			if(f[L-1]){
				modify(L-1,-1);
				f[L-1]=false;
			}
			else if(L!=1){
				modify(L-1,1);
				f[L-1]=true;
			}
			if(f[R]){
				modify(R,-1);
				f[R]=false;
			}
			else{
				modify(R,1);
				f[R]=true;
			}
		}
		else{
			int res=query(R)-query(L-1);//注意加到a[R-1]
			if(res==0)
				cout<<"Yes"<<endl;
			else
				cout<<"No"<<endl;
		}
	}
	return 0;
}

ok,以上就是本期的全部内容了。我们下期再见!

友情提示:本期的代码都有问题(除了D的代码),请不要无脑Ctrl C+Ctrl V

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
AtCoder Beginner Contest 134 是一场 AtCoder 的入门级比赛,以下是每道题的简要题解: A - Dodecagon 题目描述:已知一个正十二边形的边长,求它的面积。 解题思路:正十二边形的内角为 $150^\circ$,因此可以将正十二边形拆分为 12 个等腰三角形,通过三角形面积公式计算面积即可。 B - Golden Apple 题目描述:有 $N$ 个苹果和 $D$ 个盘子,每个盘子最多可以装下 $2D+1$ 个苹果,求最少需要多少个盘子才能装下所有的苹果。 解题思路:每个盘子最多可以装下 $2D+1$ 个苹果,因此可以将苹果平均分配到每个盘子中,可以得到最少需要 $\lceil \frac{N}{2D+1} \rceil$ 个盘子。 C - Exception Handling 题目描述:给定一个长度为 $N$ 的整数序列 $a$,求除了第 $i$ 个数以外的最大值。 解题思路:可以使用两个变量 $m_1$ 和 $m_2$ 分别记录最大值和次大值。遍历整个序列,当当前数不是第 $i$ 个数时,更新最大值和次大值。因此,最后的结果应该是 $m_1$ 或 $m_2$ 中较小的一个。 D - Preparing Boxes 题目描述:有 $N$ 个盒子和 $M$ 个物品,第 $i$ 个盒子可以放入 $a_i$ 个物品,每个物品只能放在一个盒子中。现在需要将所有的物品放入盒子中,每次操作可以将一个盒子内的物品全部取出并分配到其他盒子中,求最少需要多少次操作才能完成任务。 解题思路:首先可以计算出所有盒子中物品的总数 $S$,然后判断是否存在一个盒子的物品数量大于 $\lceil \frac{S}{2} \rceil$,如果存在,则无法完成任务。否则,可以用贪心的思想,每次从物品数量最多的盒子中取出一个物品,放入物品数量最少的盒子中。因为每次操作都会使得物品数量最多的盒子的物品数量减少,而物品数量最少的盒子的物品数量不变或增加,因此这种贪心策略可以保证最少需要的操作次数最小。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值