AtCoder Beginner Contest 353 A~E 题解

A - Buildings

找出n个大楼里比最左边大楼高(严格大于)的最左边的楼,如果没有输出-1;

边输入边找,暴力直接过;

#include<bits/stdc++.h>
using namespace std;
#define ll long long

int a,b,c,d,n,m,l,t,ans=0,sum=0; 

int v[20005];



int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n;
	int sign=0;
	cin>>a;
	for(int i=1;i<n;i++){
		cin>>b;
		if(b>a){
			cout<<i+1;
			sign=1;
			break;
		}
	}
	if(sign==0){
		cout<<-1;
	}
	return 0; 
}

B - AtCoder Amusement Park

有n个团体要坐船,每个船能坐m个人,每个团体里的人必须在一艘船上,一艘船可以同时坐多个团体,给出V1,V2..VI..Vn为按上船顺序的团体成员数,求最少需要几艘船;

暴力上船,人多了就换下艘,用l来记录当前船只的空位即可;

#include<bits/stdc++.h>
using namespace std;
#define ll long long

int a,b,c,d,n,m,l,t,ans=0,sum=0; 

int v[20005];



int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n>>m;
	ans=0;
	l=0;
	for(int i=0;i<n;i++){
		cin>>a;
		if(l<a){
			ans++;
			l=m-a;
		}
		else{
			l=l-a;
		}
	}
	cout<<ans;
	return 0; 
}

C - Sigma Problem

设 f ( x , y ) = ( x + y )%1e8 ,给出n个数,求所有数对 f ( Ai , Aj )  (1<=i<j<=n)  的和;

2≤N≤3×105,1≤Ai​<1e8

相加对1e8取余就相当于加起来大于1e8的话再减掉1e8,所有数对相加也是这样;

所以只需要把所有数对的原始和求出来,再减掉成功取余的次数k*1e8就可以了

因为Ai小于1e8,所以每一次f(x,y)最多只能减1次1e8,不需要对取余求整除;

求成功次数,先从小到大排序,再用双指针头尾往中间走就好

#include<bits/stdc++.h>
using namespace std;
#define ll long long

long long int a,b,c,d,n,m,l,t,ans=0,sum=0; 

int v[300005];



int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int p=100000000;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>v[i]; 
		sum+=v[i];
	}
	sum*=n-1;
	sort(v,v+n);
	a=0,b=n-1;
	while(a<b){
		if(v[a]+v[b]<p){
			a++;
		}
		else{
			ans+=b-a;
			b--;
		}
	}
	sum-=ans*p;
	cout<<sum;
	 
	return 0; 
}

D - Another Sigma Problem

和上题一样,f  ( x , y ) 的定义被改为了字符串加法

求所有数对 f ( Ai , Aj )  (1<=i<j<=n)  的和 结果mod998244353;

如f(3,14)=314  ,  f(3,15)=315  ,  f(14,15)=1415;

因为i<j,所以对于Aj所有的f(Ai,Aj)都相当于数列中前面的数乘上p(p=10的k次方(k=自己的位数))再加上自己,所以对每个Aj要给ans=ans +Aj-1的前缀和*p+Aj*(j-1);

由于数据量庞大,所以在许多地方需要对998244353取余,不然会爆longlong,我就是在这点上卡了还送了3个罚时;

#include<bits/stdc++.h>
using namespace std;
#define ll long long

long long int a,b,c,d,n,m,l,t,ans=0,sum=0; 

long long int v[200005];
long long int z[200005];


int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n;
	for(int i=0;i<n;i++){
		z[i]=1;
		cin>>v[i];
		ans=(ans+v[i]*i)%998244353;
		a=v[i];
		while(a>0){
			a/=10;
			z[i]*=10;
		}
		ans=(ans+(z[i]%998244353)*(sum%998244353))%998244353;
		sum=sum+v[i];
	}
	cout<<ans;
	return 0; 
}

E - Yet Another Sigma Problem

还是同上Ai变成了字符串且 f ( Ai ,  Aj )的定义变成了公共前缀的长度;

求所有 f ( Ai , Aj )  (1<=i<j<=n)  的和;

  • 2≤N≤3×105
  • ∣S1∣+∣S2∣+…+∣Sn​∣≤3×105

求多字符串的公共前缀,采用字典树,把每个字符串从首字母开始单字母地打入树,如果此层有来过就记录+1,没字符串来过就开新节点,这样每次新字符串导入的时候都能查看到前面字符串与其的公共点总和;

#include<bits/stdc++.h>
using namespace std;
#define ll long long

struct node{
	node *next[26];
	int data;
	node(){
		for(int i=0;i<26;i++){
			next[i]=NULL;
		}
		data=0;
	}
};
long long int a,b,c,d,n,m,l,t,ans=0,sum=0; 

string s;

node *find(node *head){
	node* now=head;
	for(int i=0;i<s.length();i++){
		int a=s[i]-'a';
		if(now->next[a]==NULL){
			now->next[a]=new node; 
		}
		ans+=now->next[a]->data;
		now->next[a]->data++;
		now=now->next[a];
	}
	return head;
}
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	node *head=new node;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>s;
		head=find(head);
	}
	cout<<ans;
	return 0; 
}

写的不好的地方希望大佬们指点一下

  • 14
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值