20180715练习赛 [CF]EDU ROUND 4
A - The Text Splitting CodeForces - 612A
B - HDD is Outdated Technology CodeForces - 612B
C - Replace To Make Regular Bracket Sequence CodeForces - 612C
D - The Union of k-Segments CodeForces - 612D
A
水题 直接过
给你一个字符串,让你分割成长度为p,或者长度为q的串 问你如何分割
#include<cstdio>
#define MAXN 100
int N,p,q;
char s[MAXN+10];
int main()
{
scanf("%d %d %d",&N,&p,&q);
scanf("%s",s+1);
for(int i=0;i<=MAXN;i++)
for(int j=0;j<=MAXN;j++)
if(i*p+j*q==N)
{
printf("%d\n",i+j);
int now=1;
for(int k=1;k<=i;k++)
{
for(int l=1;l<=p;l++)
printf("%c",s[now++]);
puts("");
}
for(int k=1;k<=j;k++)
{
for(int l=1;l<=q;l++)
printf("%c",s[now++]);
puts("");
}
return 0;
}
printf("-1\n");
return 0;
}
B
给出一组n的全排列的一组数(1~N,只是数字顺序乱了),求按从小到大,它们之间间隔位置的总和
也很水 注意n比较大 不能直接枚
记录每个数的位置,然后一个循环依次计算
注意要开long long
#include<cstdio>
#include<cstdlib>
using namespace std;
#define MAXN 200008
int N;
long long ans;
int a[MAXN],b[MAXN];
int main()
{
scanf("%d",&N);
for(int i=1;i<=N;i++)
{
scanf("%d",&a[i]);
b[a[i]]=i;
}
for(int i=2;i<=N;i++)
ans+=abs(b[i]-b[i-1]);
printf("%lld\n",ans);
return 0;
}
//long long 不开毁前程
C
经典的括号匹配问题 但是考场上忘了 自己搞了很久 最后搞了个数组模拟栈
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 1000005
char s[MAXN],l[MAXN];
int cnt[10],ans;
int main()
{
scanf("%s",s);
if(s[0]=='>'||s[0]=='}'||s[0]==']'||s[0]==')')
{
printf("Impossible\n");
return 0;
}
int len=strlen(s),change=0,now=0;
for(int n=0;n<len;n++)
{
if(s[n]=='<')
l[++now]=s[n];
if(s[n]=='{')
l[++now]=s[n];
if(s[n]=='[')
l[++now]=s[n];
if(s[n]=='(')
l[++now]=s[n];
if(s[n]=='>'||s[n]=='}'||s[n]==']'||s[n]==')')
{
if(now==0)
{
printf("Impossible\n");
return 0;
}
if((l[now]=='<'&&s[n]!='>')||(l[now]=='('&&s[n]!=')')||(l[now]=='{'&&s[n]!='}')||(l[now]=='['&&s[n]!=']'))
change++;
now--;
}
}
if(now>0)
{
printf("Impossible\n");
return 0;
}
printf("%d\n",change);
return 0;
}
/*
好像是个栈 一年前老师讲过 然后忘了QAQ
自己的方法一直在第10个点上WA
然后发现没有考虑左括弧多余。。。
然后就在第11个点上WA了。。。
突然发现括弧好像是不可以交叉([)] X
所以只能跟离他最近的括弧匹配 QAQ
考试的时候不会打栈
数组模拟栈
*/
后来自己还是打了个栈
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define MAXN 1000005
char s[MAXN];
stack<char> t;
bool pd(char a,char b)
{
if(a=='('&&b==')')
return 1;
if(a=='<'&&b=='>')
return 1;
if(a=='['&&b==']')
return 1;
if(a=='{'&&b=='}')
return 1;
return 0;
}
int main()
{
scanf("%s",s);
if(s[0]=='>'||s[0]=='}'||s[0]==']'||s[0]==')')
{
printf("Impossible\n");
return 0;
}
int len=strlen(s),ans=0;
for(int i=0;i<len;i++)
{
if(s[i]=='<'||s[i]=='['||s[i]=='{'||s[i]=='(')
t.push(s[i]);
if(s[i]=='>'||s[i]=='}'||s[i]==']'||s[i]==')')
{
if(t.size()==0)
{
printf("Impossible\n");
return 0;
}
else if(pd(t.top(),s[i])==0)
ans++;
t.pop();
}
}
if(t.size())
{
printf("Impossible\n");
return 0;
}
printf("%d\n",ans);
return 0;
}
D
给出n个线段问至少被覆盖k次的点的集合(实际就是求区间,这里这么描述只是表示这个区间不一定在输入里出现过)
给每个点排个序(相当于放在数轴上),标记是左端点还是右端点,设置一个cnt变量,遇到左端点+1,右端点-1,cnt==k时说明是一个答案区间的断点,同样设置一个标记变量,标记这应该是答案区间的左端点还是右端点。
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
vector<pair<int,int> > v;
vector<int> ans;
int n,k;
int main()
{
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++)
{
int l,r;
scanf("%d %d",&l,&r);
v.push_back(make_pair(l,-1));
v.push_back(make_pair(r,1));
}
sort(v.begin(),v.end());
int cnt=0;
for(int i=0;i<v.size();i++)
{
if(v[i].second==-1)
{
++cnt;
if(cnt==k)
ans.push_back(v[i].first);
}
else
{
if(cnt==k)
ans.push_back(v[i].first);
--cnt;
}
}
printf("%d\n",ans.size()/2);
for(int i=0;i<ans.size();i+=2)
printf("%d %d\n",ans[i],ans[i+1]);
return 0;
}
但是要注意的是 这道题如果碰到起点跟终点在同一个位置,则起点要排在终点的前面。
STL的vector的sort是双关键字排序,就是如果first相等,他会自动按second升序排序,而如果自己手打结构体排序的话,就要注意!
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define MAXN 1000005
#define LL long long
int n,k;
struct node{
int val,typ;
}a[MAXN*2];
vector<int>ans;
bool cmp(node p,node q)
{
if(p.val<q.val)
return 1;
if(p.val==q.val)
return p.typ>q.typ;
return 0;
}
int main()
{
scanf("%d %d",&n,&k);
for(int i=0;i<n;i++)
{
scanf("%d %d",&a[i].val,&a[i+n].val);
a[i].typ=1,a[i+n].typ=-1;
}
sort(a,a+2*n,cmp);
int cnt=0;
for(int i=0;i<2*n;i++)
{
if(a[i].typ==1) cnt++;
if(cnt==k) ans.push_back(a[i].val);
if(a[i].typ==-1) cnt--;
}
printf("%d\n",ans.size()/2);
for(int i=0;i<ans.size();i+=2)
printf("%d %d\n",ans[i],ans[i+1]);
return 0;
}
转载请注明出处,有疑问欢迎探讨
博主邮箱 2775182058@qq.com