您的位置:首页 > 其它

Codeforces Round #469 (Div. 2)

2018-03-10 18:34 363 查看

A题  水题 不解释

//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
int l,r,a;
int main(){
scanf("%d%d%d",&l,&r,&a);
if(l>r)swap(l,r);
if(l+a<r)printf("%d\n",(l+a)*2);
else{
a=a-(r-l),l=r;
printf("%d\n",l*2+a/2*2);
}
}

B题  从左到右贪心  能选就选

//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
const int N=100050;
int n,m,tempa,tempb,ans,nb=1,a
,b
;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=m;i++)scanf("%d",&b[i]);
for(int i=1;i<=n;i++){
tempa+=a[i];
while(tempb<tempa)tempb+=b[nb],nb++;
if(tempa==tempb)tempa=tempb=0,ans++;
}
printf("%d\n",ans);
}

C题     

定义以0开始和结尾  中间01相间的串是"zebra"串

给你一个串    问它能不能分成k个子序列  使得这k个子序列都是"zebra"串

Special Judge

 

开两个set  分别存 0 1  出现的位置

贪心选取即可

//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
const int N=200500;
char s
;
set<int>a,b;
vector<int>vec
;
set<int>::iterator ita,itb;
int top,n;
int main(){
scanf("%s",s+1),n=strlen(s+1);
for(int i=1;i<=n;i++){
if(s[i]=='0')a.insert(i);
else b.insert(i);
}
while(!b.empty()){
if(a.empty()){puts("-1");return 0;}
ita=a.begin();
vec[++top].push_back(*ita);
while(1){
//            printf("*ita=%d\n",*ita);
itb=b.lower_bound(*ita);
//            printf("itb=%d\n",*itb);
if(itb==b.end()){a.erase(ita);break;}
//            printf("!");
a.erase(ita);
vec[top].push_back(*itb);
ita=a.lower_bound(*itb);
if(ita==a.end()){puts("-1");return 0;}
vec[top].push_back(*ita);
b.erase(itb);
}
}
while(!a.empty()){
vec[++top].push_back(*(ita=a.begin()));
//        printf("%d\n",*ita);
a.erase(ita);
}
printf("%d\n",top);
for(int i=1;i<=top;i++){
printf("%d ",vec[i].size());
for(int j=0;j<vec[i].size();j++){
printf("%d ",vec[i][j]);
}puts("");
}
}

D题   

找规律

n是奇数 -> 前n/2+1的数的位置不变   剩下的递归n/2并插空  循环右移一个位置

n是偶数 ->前n/2的数的位置不变   递归n/2

 

//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
#define int long long
int solve(int x,int y){
if((y&1)&&x<=y&&(x&1))return x/2+1;
else if(((y&1)==0)&&x<y&&(x&1))return x/2+1;
else if((y&1)==1){
if(x==2)return solve(y/2,y/2)+y/2+1;
else return solve(x/2-1,y/2)+y/2+1;
}
elsereturn solve(x/2,y/2)+y/2;
}
int n,q,x;
signed main(){
scanf("%I64d%I64d",&n,&q);
while(q--){
scanf("%I64d",&x);
printf("%I64d\n",solve(x,n));
}
}

E 连边tarjan 找入度为0的且点数最小的强连通分量

连边的要求  x=(y+1)%h  x->y连边

//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
const int N=200050;
int n,m,h,u
,xx,yy,v
,nxt
,first
,tot,ans=0x3f3f3f3f;
int low
,dfn
,cnt,vis
,s
,p
,top,t,V
,tempans,out
;
void add(int x,int y){v[tot]=y,nxt[tot]=first[x],first[x]=tot++;}
void tarjan(int x){
low[x]=dfn[x]=++cnt;vis[x]=1;s[++top]=x;
for(int i=first[x];~i;i=nxt[i])
if(!dfn[v[i]])tarjan(v[i]),low[x]=min(low[x],low[v[i]]);
else if(vis[v[i]])low[x]=min(low[x],dfn[v[i]]);
if(low[x]==dfn[x]){t++;do xx=s[top--],vis[xx]=0,p[xx]=t,V[t]++;while(xx!=x);}
}
int main(){
memset(first,-1,sizeof(first));
scanf("%d%d%d",&n,&m,&h);
for(int i=1;i<=n;i++)scanf("%d",&u[i]);
for(int i=1;i<=m;i++){
scanf("%d%d",&xx,&yy);
if(u[xx]==(u[yy]+1)%h)add(yy,xx);
if(u[yy]==(u[xx]+1)%h)add(xx,yy);
}
for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
for(int i=1;i<=n;i++)
for(int j=first[i];~j;j=nxt[j])
if(p[i]!=p[v[j]])out[p[i]]=1;
for(int i=1;i<=n;i++){
if(!out[p[i]]&&ans>V[p[i]])tempans=p[i],ans=V[p[i]];
}printf("%d\n",ans);
for(int i=1;i<=n;i++)if(p[i]==tempans)printf("%d ",i);
}

贪心

//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,d,b,a[100050],cntl,cntr;
int sum(int l,int r){
if(l<1)l=1;if(r>n)r=n;
return a[r]-a[l-1];
}
signed main(){
scanf("%I64d%I64d%I64d",&n,&d,&b);
for(int i=1;i<=n;i++)scanf("%I64d",&a[i]),a[i]+=a[i-1];
for(int i=1;i<=n/2;i++){
if(sum(1,i*(d+1))>=(cntl+1)*b)cntl++;
if(sum(n-i+1-i*d,n)>=(cntr+1)*b)cntr++;
}printf("%I64d\n",max(n/2-cntl,n/2-cntr));
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: