Codeforces Round #313 (Div. 2) A-E

題目鏈接
A.腦筋急轉彎

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
int n,a[N];
int main() {
  ios::sync_with_stdio(false);
  cin>>n;
  for(int i=1;i<=n;i++){
    cin>>a[i];
    if(a[i]==1)return cout<<-1,0;
  }
  cout<<1<<'\n';
  return 0;
}

B.所有情況判一判

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
int a[5],b[5];
int main() {
  ios::sync_with_stdio(false);
  for(int i=1;i<=3;i++){
    cin>>a[i]>>b[i];
  }
  if(a[2]+a[3]<=a[1]&&max(b[2],b[3])<=b[1])cout<<"YES\n";
  else if(b[2]+b[3]<=b[1]&&max(a[2],a[3])<=a[1])cout<<"YES\n";
  else{
    swap(a[2],b[2]);
    if(a[2]+a[3]<=a[1]&&max(b[2],b[3])<=b[1])cout<<"YES\n";
    else if(b[2]+b[3]<=b[1]&&max(a[2],a[3])<=a[1])cout<<"YES\n";
    else{
      swap(a[3],b[3]);
      if(a[2]+a[3]<=a[1]&&max(b[2],b[3])<=b[1])cout<<"YES\n";
      else if(b[2]+b[3]<=b[1]&&max(a[2],a[3])<=a[1])cout<<"YES\n";
      else{
        swap(a[2],b[2]);
        if(a[2]+a[3]<=a[1]&&max(b[2],b[3])<=b[1])cout<<"YES\n";
        else if(b[2]+b[3]<=b[1]&&max(a[2],a[3])<=a[1])cout<<"YES\n";
        else cout<<"NO\n";
      }
    }
  }
 
 
  return 0;
}

C.補成一個梯形,去掉多餘的部分

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
int a[N],b[N];
LL get(){
  LL ans=0;
 // for(int i=1;i<=6;i++)cout<<a[i]<<' ';
 int num=a[2]+1;
  for(int i=1;i<=a[6]+a[1];i++){
    ans+=2*num-1;
    num++;
  }
  for(int i=1;i<=a[6];i++){
    ans-=(2*i-1);
  }
  for(int i=1;i<=a[4];i++){
    ans-=(2*i-1);
  }
 
  return ans;
}
int main() {
  //120
  ios::sync_with_stdio(false);
  for(int i=1;i<=6;i++)cin>>a[i];
  //
  cout<<get()<<'\n';
  return 0;
}

D.直接分治判斷一下即可

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
char a[N],b[N];
int ch(int l,int  r,int x,int y){
  int dx=l+r>>1;
  int dy=x+y>>1;
  int sta=0;
  for(int i=l;i<=r;i++){
    if(a[i]!=b[x+i-l]){
      sta=1;
      break;
    }
  }
//  cout<<l<<' '<<r<<' '<<x<<' '<<y<<' '<<sta<<endl;
  if(!sta)return 1;
  if((r-l+1)%2==0 && (y-x+1)%2==0){
    if(ch(l,dx,x,dy)&&ch(dx+1,r,dy+1,y))return 1;
    if(ch(l,dx,dy+1,y)&&ch(dx+1,r,x,dy))return 1;
  }
  return 0;
}
int main() {
  ios::sync_with_stdio(false);
  cin>>a+1>>b+1;
  int l=strlen(a+1);
  if(ch(1,l,1,l))cout<<"YES\n";
  else cout<<"NO\n";
  return 0;
}

E.
題意:一個n*m的棋盤,從左上角走到右下角,有m個違法格子不能經過,問你有多少種方式。
答案顯然等於:總方案-不合法方案。
如何計算不合法方案呢?
我們對每個不能經過的格子進行討論:一個格子所能貢獻的方案爲,左上角到它的方案乘以它到右下角的方案,這樣顯然會多算很多。 那麼用分治的思想來看的話,每個不能經過的格子就是一個小棋盤,找到從左上角到它的位置且不經過違法點的方案數fif_i。顯然就可以解決這個問題了。


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
LL fac[N],inv[N];
const LL mod=1e9+7;
LL km(LL a,LL b){
  LL ans=1;
  while(b){
    if(b&1)ans=a*ans%mod;
    b>>=1;
    a=a*a%mod;
  }
  return ans;
}
int a[N],b[N],n,m,k;
void init(){
  fac[0]=1;
  for(int i=1;i<N;i++)fac[i]=fac[i-1]*i%mod;
  inv[N-1]=km(fac[N-1],mod-2);
  for(int i=N-2;i>=0;i--)inv[i]=inv[i+1]*(i+1)%mod;
}
LL get(int x,int y){
  return fac[x]*inv[y]%mod*inv[x-y]%mod;
}
struct uzi{
  int a,b;
  bool operator <(const uzi &t)const{
    if(a==t.a)return b<t.b;
    return a<t.a;
  }
}p[N];
LL tmp[N];
int main() {
  ios::sync_with_stdio(false);
  init();
  cin>>n>>m>>k;
  for(int i=1;i<=k;i++)cin>>p[i].a>>p[i].b;
  LL ans=get(n+m-2,m-1);
  sort(p+1,p+1+k);
  for(int i=1;i<=k;i++){
    int sta=0;
    LL tot=0;
    tmp[i]=get(p[i].a+p[i].b-2,p[i].b-1);
    for(int j=1;j<i;j++){
      if(p[j].b<=p[i].b){
        sta=1;
        tot+=tmp[j]*get(p[i].a+p[i].b-p[j].a-p[j].b,p[i].b-p[j].b)%mod;
        tot%=mod;
      }
    }
    if(!sta){
      tmp[i]=get(p[i].a+p[i].b-2,p[i].b-1);
    }else{
      tmp[i]-=tot;
      tmp[i]=(tmp[i]+mod)%mod;
    }
    ans-=tmp[i]*get(n+m-p[i].a-p[i].b,m-p[i].b)%mod;
    ans=(ans+mod)%mod;
  }
  cout<<ans<<'\n';
  return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章