热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:CodeforcesRound#506(Div.3)题解

本文由编程笔记#小编为大家整理,主要介绍了CodeforcesRound#506(Div.3)题解相关的知识,希望对你有一定的参考价值。
本文由编程笔记#小编为大家整理,主要介绍了Codeforces Round #506 (Div. 3) 题解相关的知识,希望对你有一定的参考价值。


Codeforces Round #506 (Div. 3)

题目总链接:https://codeforces.com/contest/1029

A. Many Equal Substrings

题意:

给出长度为n的字符串,然后要求你添加一些字符,使得有k个这样的字符串。

题解:

直接暴力吧...一个指针从1开始,另一个从2开始,逐一比较看是否相同;如果不同,第一个指针继续回到1,第二个指针从3开始...就这么一直重复。最后如果第二个指针能够顺利到最后一位,那么记录当前的第一个指针,把他后面的串取出来添加k-1个就ok了。

代码如下:


技术分享图片技术分享图片

#include
using namespace std;
typedef
long long ll;
const int N = 55;
string s;
int n,k;
int main(){
cin
>>n>>k;
cin
>>s;
int fir = 0,last = 1;
for(int i=1;i){
if(s[fir]==s[i]) fir++;
else if(fir) fir = 0,i=last+1,last=i;
}
string tmp = s.substr(fir,n);
for(int i=1;itmp;
cout<<s;
return 0;
}


View Code

 

B. Creating the Contest

题意:

给出n个数,选出最长的区间,满足区间中的相邻两个数a,b有2*a>=b且a

题解:

枚举+判断一下就ok了。

代码如下:


技术分享图片技术分享图片

#include
using namespace std;
typedef
long long ll ;
const int N = 2e5+5;
ll a[N];
int n;
int main(){
scanf(
"%d",&n);
int l=1,r=1,ans=1;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=2;i<=n;i++){
if(a[i]<=a[i-1]*2){
r
++;
ans
=max(ans,r-l+1);
}
else{
l
=r=i;
}
}
cout
<<ans;
return 0;
}


View Code

 

C. Maximal Intersection

题意:

给出n个区间,然后你可以任意去掉一个区间,最后求区间交集的最大值为多少。

题解:

区间的交集就是[maxl,minr]...根据这个求出前缀、后缀的l和r,然后枚举去掉哪个区间就行了。注意一下这里区间的交集是所有区间的交集。

代码如下:


技术分享图片技术分享图片

#include
#define INF 0x3f3f3f3f
using namespace std;
typedef
long long ll;
const int N = 3e5+5;
int n;
struct line{
int l,r;
}p[N];
int prel[N],prer[N],sufl[N],sufr[N];
int main(){
scanf(
"%d",&n);
memset(prer,INF,
sizeof(prer));
memset(sufr,INF,
sizeof(sufr));
for(int i=1;i<=n;i++) scanf("%d%d",&p[i].l,&p[i].r);
for(int i=1;i<=n;i++){
prel[i]
=max(prel[i-1],p[i].l);
prer[i]
=min(prer[i-1],p[i].r);
}
for(int i=n;i>=1;i--){
sufl[i]
=max(sufl[i+1],p[i].l);
sufr[i]
=min(sufr[i+1],p[i].r);
}
int ans = 0;
for(int i=1;i<=n;i++){
int l = max(prel[i-1],sufl[i+1]);
int r = min(prer[i-1],sufr[i+1]);
ans
=max(ans,r-l);
}
printf(
"%d",ans);
return 0;
}


View Code

 

D. Concatenated Multiples

题意:

给出n个数以及k,现在将任意两个数聚合成为一对,比如12和345聚合就为12345,问一共有多少对能被k整除。

题解:

将a,b聚合,聚合之后的数即位a*10^len(b)+b,如果满足(a*10^len(b)+b%k)==0,则有a*10^len(b)%k+b%k=k or 0。

根据这个来写就好了,最后时间复杂度为O(10*nlogn)。

代码如下:


技术分享图片技术分享图片

#include
using namespace std;
typedef
long long ll;
const int N = 2e5+5;
ll n,k;
ll a[N],b[N],len[N],q[
12];
vector
vec[12];
int main(){
scanf(
"%I64d%I64d",&n,&k);
q[
0]=1;
for(int i=1;i<=10;i++) q[i]=q[i-1]*10%k;
for(int i=1;i<=n;i++) scanf("%I64d",&a[i]);
sort(a
+1,a+n+1);
for(int i=1;i<=n;i++) b[i]=a[i];
for(int i=1;i<=n;i++){
ll x
=a[i];
int cnt=0;
while(x){
x
/=10;
cnt
++;
}
len[i]
=cnt;
}
for(int i=1;i<=10;i++){
for(int j=1;j<=n;j++)
vec[i].push_back(a[j]
*q[i]%k);
sort(vec[i].begin(),vec[i].end());
}
ll ans
= 0;
for(int i=1;i<=n;i++){
b[i]
%=k;
int l = len[i];
int pos1 = lower_bound(vec[l].begin(),vec[l].end(),(k-b[i])%k)-vec[l].begin();
int pos2 = upper_bound(vec[l].begin(),vec[l].end(),(k-b[i])%k)-vec[l].begin();
ans
+=(pos2-pos1);
if(a[i]*q[l]%k==(k-b[i])%k)ans--;
}
printf(
"%I64d",ans);
return 0;
}


View Code

 

 

F. Multicolored Markers

题意:

给出a和b,代表两种颜色的格子数目。现在用他们围成一个矩形,还要要求至少有一种颜色围成一个矩形。现在求最短周长为多少。

题解:

用sqrt(a+b)的时间复杂度可以求出大矩形的因子有哪些。然后枚举每个因子,再来判断一下a or b是否能在我们枚举出来的长以及宽内围成一个矩形就行了。

我的做法时间复杂度比较高,说一个时间复杂度比较低的解法吧。

就是假定我们现在来判断a是否能围成矩形,那么我们要用sqrt(a)的时间复杂度来求出所有的因子,我们把宽度从小到大来存。对于大矩形也是这样。然后如果大矩形确定了长l,宽w,那么小矩形我们就贪心得选择最大的宽w‘同时满足w‘<=w,那么此时l‘就是最小,然后判断一下此时是否l‘<=l就行了。

之后就继续增大w,重复上面的操作...最后维护一下答案就行了。

我的暴力代码..


技术分享图片技术分享图片

#include
using namespace std;
typedef
long long ll;
ll a,b,c;
vector
v1,v2,v3;
bool check(ll l,ll s){
ll r
=s/l;
for(auto width:v2){
ll len
= c/width;
if(width<=l && len<=r) return true;
}
return false;
}
int main(){
cin
>>a>>b;
ll s
=a+b;
c
=a;
for(ll i=1;i*i<=s;i++)
if(s%i==0) v1.push_back(i);
for(ll i=1;i*i<=c;i++)
if(c%i==0) v2.push_back(i);
ll ans;
for(int i=v1.size()-1;i>=0;i--){
ll l
=v1[i],r=s/v1[i];
if(check(l,s)){
ans
= (v1[i]+s/v1[i])*2;
break ;
}
}
c
=b;v2.clear();
for(ll i=1;i*i<=c;i++)
if(c%i==0) v2.push_back(i);
for(int i=v1.size()-1;i>=0;i--){
ll l
=v1[i],r=s/v1[i];
if(check(l,s)){
ans
= min((v1[i]+s/v1[i])*2,ans);
break ;
}
}
printf(
"%I64d",ans);
return 0;
}


View Code

 


推荐阅读
author-avatar
CC2502916775_645
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有