Codeforces Global Round 3
A.2c+2min(a,b)+(a!=b)
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 6 typedef long long ll; 7 using namespace std; 8 9 int a,b,c; 10 11 int main(){ 12 cin>>a>>b>>c; 13 cout<<2ll*c+2ll*min(a,b)+(abs(b-a)>=1)<<endl; 14 return 0; 15 }
B.必定是删除一些第一部分航班之后删除一些紧接着的第二部分航班,枚举第一部分删多少个,two-pointers。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 5 using namespace std; 6 7 const int N=200010; 8 int n,m,k,ta,tb,a[N],b[N]; 9 10 int main(){ 11 scanf("%d%d%d%d%d",&n,&m,&ta,&tb,&k); 12 rep(i,1,n) scanf("%d",&a[i]); 13 rep(i,1,m) scanf("%d",&b[i]); 14 if (k>=min(n,m)){ printf("-1\n"); return 0; } 15 int now=1,ans=0; 16 rep(i,1,n){ 17 if (i-1>k) break; 18 while (a[i]+ta>b[now] && now<=m) now++; 19 int rest=k-(i-1); 20 if (now+rest>m){ ans=-1; break; } 21 ans=max(ans,b[now+rest]+tb); 22 } 23 printf("%d\n",ans); 24 return 0; 25 }
C.找到每个数应该在的位置并想办法在5次之内把它放到那里去。做法很多,具体见代码。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 6 typedef long long ll; 7 using namespace std; 8 9 const int N=3000010; 10 int n,tot,a[N],id[N],p[N]; 11 struct P{ int a,b; }q[N]; 12 13 bool cmp(int x,int y){ return a[x]<a[y]; } 14 15 void work(int x,int y){ q[++tot]=(P){x,y}; swap(p[x],p[y]); swap(id[p[x]],id[p[y]]); } 16 17 void Swap(int x,int y){ 18 if (x>y) swap(x,y); 19 if (y-x>=n/2) { work(x,y); return; } 20 if (x<=n/2){ 21 if (y<=n/2) work(x,n),work(y,n),work(x,n); else work(x,n),work(n,1),work(1,y),work(1,n),work(n,x); 22 }else work(x,1),work(1,y),work(x,1); 23 } 24 25 int main(){ 26 scanf("%d",&n); 27 rep(i,1,n) scanf("%d",&a[i]),id[i]=i; 28 sort(id+1,id+n+1,cmp); 29 rep(i,1,n) p[id[i]]=i; 30 rep(i,1,n) if (id[i]!=i) Swap(id[i],i); 31 printf("%d\n",tot); 32 rep(i,1,tot) printf("%d %d\n",q[i].a,q[i].b); 33 return 0; 34 }
D.答案就是max(ai<bi的数对数,ai>bi的数对数),因为当ai<bi时把ai从大到小排一定是一个合法解,ai>bi同理。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 6 typedef long long ll; 7 using namespace std; 8 9 const int N=300010; 10 int n,s1,s2,tot,q[N]; 11 struct P{ int a,b; }p[N]; 12 13 bool cmp1(int a,int b){ return p[a].a<p[b].a; } 14 bool cmp2(int a,int b){ return p[a].a>p[b].a; } 15 16 int main(){ 17 scanf("%d",&n); 18 rep(i,1,n){ 19 scanf("%d%d",&p[i].a,&p[i].b); 20 if (p[i].a>p[i].b) s1++; else s2++; 21 } 22 if (s1>s2){ 23 rep(i,1,n) if (p[i].a>p[i].b) q[++tot]=i; 24 sort(q+1,q+tot+1,cmp1); printf("%d\n",s1); 25 rep(i,1,tot) printf("%d ",q[i]); 26 }else{ 27 rep(i,1,n) if (p[i].a<p[i].b) q[++tot]=i; 28 sort(q+1,q+tot+1,cmp2); printf("%d\n",s2); 29 rep(i,1,tot) printf("%d ",q[i]); 30 } 31 return 0; 32 }
E.注意到无论怎么操作石子之间的相对位置都是不变的,于是每个t分别对应哪个s也是确定的。把石子分成两类,si<ti和si>ti,从左到右依次考虑每个第一类石子,找到它后面的最近的第二类石子来完成操作。若所有石子位移总和不为0或中间有某个第一类石子后面找不到第二类石子则必定无解。
1 #include<cstdio> 2 #include<algorithm> 3 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 4 typedef long long ll; 5 using namespace std; 6 7 const int N=3000010; 8 ll s1,s2; 9 int n,n1,n2,num,t[N]; 10 struct P{ int s,id; }a[N],a1[N],a2[N]; 11 struct Q{ int x,y,d; }q[N]; 12 bool operator <(const P &a,const P &b){ return a.s<b.s; } 13 14 int main(){ 15 scanf("%d",&n); 16 rep(i,1,n) scanf("%d",&a[i].s),s1+=a[i].s,a[i].id=i; 17 rep(i,1,n) scanf("%d",&t[i]),s2+=t[i]; 18 if (s1!=s2){ puts("NO"); return 0; } 19 sort(a+1,a+n+1); sort(t+1,t+n+1); 20 rep(i,1,n){ 21 if (a[i].s<t[i]) a1[++n1]=(P){t[i]-a[i].s,i}; 22 if (a[i].s>t[i]) a2[++n2]=(P){a[i].s-t[i],i}; 23 } 24 int j=1; 25 rep(i,1,n1){ 26 int s=a1[i].s; 27 while (s){ 28 if (a1[i].id>a2[j].id){ puts("NO"); return 0; } 29 if (s<a2[j].s) q[++num]=(Q){a[a1[i].id].id,a[a2[j].id].id,s},a2[j].s-=s,s=0; 30 else q[++num]=(Q){a[a1[i].id].id,a[a2[j].id].id,a2[j].s},s-=a2[j].s,j++; 31 } 32 } 33 printf("YES\n%d\n",num); 34 rep(i,1,num) printf("%d %d %d\n",q[i].x,q[i].y,q[i].d); 35 return 0; 36 }
F.考虑将每个数的贡献算到它的最低位1上去,那么我们要做的就是对于每一位让它的贡献与初始总和反号。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 5 typedef long long ll; 6 using namespace std; 7 8 const int N=300010; 9 int n; 10 ll sm,ans,a[N],mk[N]; 11 12 int main(){ 13 ios::sync_with_stdio(false); 14 cin>>n; 15 rep(i,1,n) cin>>a[i]>>mk[i],sm+=a[i]; 16 if (sm<0) rep(i,1,n) a[i]=-a[i]; 17 for (int i=62; ~i; i--){ 18 sm=0; 19 rep(j,1,n) if (mk[j]==1ll<<i) sm+=a[j]; 20 if (sm>0) ans|=1ll<<i; 21 rep(j,1,n) if (mk[j]&(1ll<<i)){ 22 mk[j]^=1ll<<i; 23 if (sm>0) a[j]=-a[j]; 24 } 25 } 26 cout<<ans<<endl; 27 return 0; 28 }