AtCoder Beginner Contest 353(A-F)

  • A-Buildings

保存第一个建筑的高度,然后只要后面出现比它高的输出即可。


#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10,mod=1e9+7;
signed main()
{
    std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int n; cin>>n;
    vector<int>a(n+1);
    int pos=-1;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        if(a[i]>a[1]&&pos==-1) pos=i; 
    }
    cout<<pos<<'\n';
    return 0;
}
 
  • B - AtCoder Amusement Park

直接模拟即可,能分就分,不够的话直接重置即可

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10,mod=1e9+7;
signed main()
{
    std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int n,k; cin>>n>>k;
    vector<int>a(n+1);
    int tmp=k,res=1;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        if(tmp>=a[i]) tmp-=a[i];
        else tmp=k-a[i],res++;
    }
    cout<<res<<'\n';
    return 0;
}

  • C - Sigma Problem

对于如果没有取模的限制,考虑所有的数,也就是所有的数都被加了$ n-1 $次,现在考虑取模,首先我们要将所有的数排序,这样才能满足单调性,然后对于小于\(5e7\)的数来说,它加它前面的数一定不满足取模性质,对于大于的数,我们从这个数前面的数开始一直向前左移,直到两数之和小于\(1e8\)结束,对于其后面所有的数,一定满足前面的取模性质,只需要考虑有没有更小的数使得再次满足性质即可,换句话来说就是对于每个数都要找到其最小的满足取模性质的数即可

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10,mod=1e9+7;
signed main()
{
    std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int n; cin>>n;
    vector<int>a(n+1);
    int res=0;
    for(int i=1;i<=n;i++) cin>>a[i],res+=(n-1)*a[i];
    sort(a.begin(),a.end());
    int r=-1;
    for(int i=1;i<=n;i++){
        if(a[i]>=50000000){
            if(r==-1) r=i-1;
            while(r>=1&&a[r]+a[i]>=100000000) r--;
            res-=100000000*(i-r-1);
        }
    }
    cout<<res;
    return 0;
}
  • D - Another Sigma Problem

直接记录下来所有数的长度,然后从头开始遍历,对于每个数来说,它后面的数一定会用到它,所以直接考虑扩展次数相乘即可,然后考虑相加,对于\(i\)位置的数,其一定不会扩展\(i-1\)次,换句话也就是单纯加了这些次

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10,mod=998244353;
int qpow(int a,int k){
    int res=1;
    while(k){
        if(k&1) res*=a,res%=mod;
        k>>=1,a*=a,a%=mod;
    }
    return res;
}
signed main()
{
    std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int n; cin>>n;
    vector<int>a(n+1);
    map<int,int>mp;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        string s=to_string(a[i]);
        mp[s.size()]++;
    }
    int res=0;
    for(int i=1;i<=n;i++){
        res=(res+((i-1)*a[i])%mod)%mod;
        string s=to_string(a[i]);
        mp[s.size()]--;
        for(auto x:mp){
            int now=qpow(10,x.first);
            // cout<<a[i]<<' '<<x.second<<' '<<now<<' '<<now*x.second*a[i]<<'\n';
            res=(res+((now*x.second)%mod*a[i])%mod)%mod;
        }
    }
    cout<<res<<'\n';
    return 0;
}
  • E - Yet Another Sigma Problem

直接字典树求出所有的贡献就可以了,这个没什么好说的,如果是第一次出现那就不要计算贡献次数,如果不为一的话就直接计算即可

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10,mod=1e9+7;
struct node{
    int cnt,son[30];
}tr[N];
signed main()
{
    std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int n;cin>>n;;
    int idx=0,res=0;
    for(int i=1;i<=n;i++){
        string s; cin>>s;
        int cur=0;
        for(auto c:s){
            c-='a';
            if(!tr[cur].son[c]) tr[cur].son[c]=++idx;
            cur=tr[cur].son[c],tr[cur].cnt++;
        }
    }  
    for(int i=1;i<=idx;i++) res+=tr[i].cnt*(tr[i].cnt-1)/2;
    cout<<res<<'\n';
    return 0;
}
  • F - Tile Distance

分类讨论:
首先明确一点,由于L块的存在,我们两个点一定都要先去相邻的L块
对于\(k=1\)的情况,很明显的就是曼哈顿距离
对于\(k=2\)的情况,由于我们从一个L块到另一个L块的消耗是2,例如我们存在两个L块:(1,0),(5,0)那么如果我们只走L块的话消耗为4,而我们直接通过:L->S->L这样的消耗为3,所以说肯定我们直着走更优
对于\(k>=3\),那么我们肯定要沿着对角线走,这样每次走到左边相邻的块的消耗为4,是最小的,那么我们此时将坐标轴旋转\(45°\)然后求曼哈顿距离即可

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10,mod=1e9+7;
vector<array<int,3>>make(int x,int y,int k){
	x+=k,y+=k;
	vector<array<int,3>>res;
	if(((x/k)+(y/k))%2)
		return res.push_back({x/k,y/k,0}),res;
	res.push_back({x/k,y/k+1,k-y%k});
	res.push_back({x/k,y/k-1,y%k+1});
	res.push_back({x/k-1,y/k,x%k+1});
	res.push_back({x/k+1,y/k,k-x%k});
	return res;
}
signed main()
{
	std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	int k,sx,sy,tx,ty; cin>>k>>sx>>sy>>tx>>ty;
	int res=abs(sx-tx)+abs(sy-ty);
	if(k==1) return cout<<res<<'\n',0;
	auto v1=make(sx,sy,k);
	auto v2=make(tx,ty,k);
	auto get=[&](int x1,int y1,int x2,int y2,int k)->int{
		int dx=abs(x1-x2);
		int dy=abs(y1-y2);
		if(k==2) return dx+dy+abs(dx-dy)/2;
		int x1_=x1+y1,y1_=y1-x1;
		int x2_=x2+y2,y2_=y2-x2;
		return abs(x1_-x2_)+abs(y1_-y2_);
	};
	for(auto s:v1)
		for(auto t:v2)
			res=min(res,s[2]+t[2]+get(s[0],s[1],t[0],t[1],k));
	cout<<res<<'\n';
	return 0;
}
posted @ 2024-05-15 10:32  o-Sakurajimamai-o  阅读(22)  评论(0编辑  收藏  举报
-- --