zoukankan      html  css  js  c++  java
  • 2018徐州邀请赛

    题目链接: https://www.jisuanke.com/contest/1408

    A题

    模拟一个BFS,输出最后一轮(层)被搜索的点中坐标最小的,比较坑的是 K==N*M 需要特判

     1 #include <bits/stdc++.h>
     2 #define fst first
     3 #define scd second
     4 #define ingrid(x,y) (x)>=1&&(x)<=N&&(y)>=1&&(y)<=M
     5 using namespace std;
     6 typedef pair<int ,int > pii;
     7 
     8 bool graph[2001][2001];
     9 queue< pii > Q;
    10 int N,M;
    11 int dx[4]={0,0,1,-1};
    12 int dy[4]={1,-1,0,0};
    13 
    14 pii getmin(pii a,pii b){
    15     if(a.fst!=b.fst) return a.fst<b.fst?a:b;
    16     return a.scd<=b.scd?a:b;
    17 }
    18 
    19 int main(){
    20     while(~scanf("%d%d",&N,&M)){
    21         int K;
    22         scanf("%d",&K);
    23         pii ans;
    24         memset(graph,false,sizeof(graph));
    25         while(!Q.empty()) Q.pop();
    26         for(int i=0;i<K;++i){
    27             pii tmp;
    28             scanf("%d%d",&tmp.fst,&tmp.scd);
    29             graph[tmp.fst][tmp.scd]=true;
    30             Q.push(tmp);
    31             ans=tmp;
    32         }
    33         if(K==N*M) { printf("%d %d
    ",ans.fst,ans.scd);continue;}
    34         int tot=0;
    35         for(;;){
    36             if(tot==N*M) break;
    37             pii mm=make_pair(N+1,M+1);
    38             int cnt=Q.size();
    39             tot+=cnt;
    40             while(cnt--){
    41                 pii u=Q.front();Q.pop();
    42                 int ux=u.fst,uy=u.scd;
    43                 for(int i=0;i<4;++i){
    44                     int nx=ux+dx[i],ny=uy+dy[i];
    45                     if(ingrid(nx,ny)&&graph[nx][ny]==false){
    46                         pii tmp=make_pair(nx,ny);
    47                         graph[nx][ny]=true;
    48                         Q.push(tmp);
    49                         mm=getmin(mm,tmp);
    50                     }
    51                 }
    52             }
    53             if(Q.size()+tot==N*M) {
    54                 ans=mm;
    55                 break;    
    56             }
    57         }
    58         printf("%d %d
    ",ans.fst,ans.scd);
    59     }
    60     return 0;
    61 }
    View Code

    B题

    元素为(1~N)的序列,问逆序对有K个时,有几种排列。

    1

    1 1

    1 2 2 1

    1 3 5 6 5 3 1

    ... ...

    设逆序对个数 num(N,K)表示 长度为N,逆序对个数为K的排列组合个数,有递推式 num(N+1,K)=num(N,K)+num(N+1,K-1)-num(N,K-N-1) ;num(N,0)=1

    //luogu有类似题目

    此题比较坑的地方是卡内存,必须储存询问,离线用滚动数组计算递推式。间接排序是个好东西。

     1 #include <bits/stdc++.h>
     2 #define fst first
     3 #define scd second
     4 using namespace std;
     5 
     6 typedef pair<int ,int > pii;
     7 const int MOD=1e9+7;
     8 int num[2][5001];
     9 int ans[5001];
    10 pii query[5001];
    11 int _id[5001];
    12 int tmpid; 
    13 void solve(){
    14     int cntid=1;
    15     int cur=0;
    16     for(int i=0;i<5000;++i){
    17         memset(num[cur^1],0,sizeof(num[cur^1]));
    18         num[cur^1][0]=1;
    19         int bound=i*(i+1)/2;
    20         for(int j=1;j<=5000&&j<=bound;++j)
    21         {
    22             if(j-i-1>=0) num[cur^1][j]=((num[cur^1][j-1]+num[cur][j])%MOD-num[cur][j-i-1]+MOD)%MOD;
    23             else num[cur^1][j]=(num[cur^1][j-1]+num[cur][j])%MOD;
    24         }
    25         cur^=1;
    26         while(cntid<tmpid&&i+1==query[_id[cntid]].fst) {
    27             int KK=query[_id[cntid]].scd;
    28             ans[_id[cntid]]=num[cur][KK];
    29             cntid++;// Don't forget ! 
    30         }
    31     }
    32 }
    33 
    34 int N,K;
    35 
    36 bool cmp(int i,int j){
    37     pii a=query[i],b=query[j];
    38     if(a.fst!=b.fst)return a.fst<b.fst;
    39     return a.scd<b.scd;
    40 }
    41 
    42 int main(){
    43     tmpid=1;
    44     while(~scanf("%d%d",&N,&K)){
    45         _id[tmpid]=tmpid;
    46         query[tmpid]=make_pair(N,K);
    47         tmpid++;
    48     }
    49     sort(_id+1,_id+tmpid,cmp);
    50     solve();
    51     for(int i=1;i<tmpid;++i){
    52         printf("%d
    ",ans[i]);
    53     }
    54     return 0;
    55 }
    View Code

    D题

    了解题意后答案就是一系列组合数的积,可以将这一系列组合数的积,转化公式( ∑Ui)!/∏(Ui!)

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define fst    first
     4 #define scd second
     5 typedef pair<int ,int > pii;
     6 typedef long long ll;
     7 
     8 const ll MOD=1e9+7;
     9 
    10 ll F[1000000+6];
    11 ll ans;
    12 
    13 void init(){
    14     F[1]=1;F[2]=2;
    15     for(ll i=3;i<=1000000;++i)
    16         F[i]=F[i-1]*i%MOD;
    17 }
    18 
    19 ll inv(ll a,ll m){
    20     if(a==1) return 1;
    21     return inv(m%a,m)*(m-m/a)%m;
    22 }
    23 
    24 int tot;
    25 int A[1000000+6];
    26 int main(){
    27     init();
    28     int N;
    29     while(~scanf("%d",&N)){
    30         tot=0;
    31         for(int i=0;i<N;++i) {
    32             scanf("%d",&A[i]);
    33             tot+=A[i];
    34         }
    35         ans=F[tot];
    36         for(int i=0;i<N;++i) {
    37             ans=ans*inv(F[A[i]],MOD)%MOD;
    38         }
    39         printf("%lld
    ",ans);
    40     }
    41     return 0;
    42 }
    View Code

    E题

    终点拆成两个点, 推出公式即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 typedef long long ll;
     5 const ll MOD=1e9+7;
     6 ll F[2048];
     7 
     8 void init(){
     9     F[0]=1;F[1]=1;
    10     for(ll i=2;i<=2000;++i)
    11         F[i]=F[i-1]*i%MOD;
    12     return;
    13 }
    14 
    15 ll qpow(ll a,ll b,ll mod){
    16     ll ret=1ll%mod;
    17     while(b){
    18         if(b&1ll) ret=ret*a%mod;
    19         a=a*a%mod;
    20         b>>=1;
    21     }
    22     return ret;
    23 }
    24 
    25 ll ex_gcd(ll a,ll b,ll& x,ll& y){
    26     if(a==0&&b==0) return -1;
    27     if(b==0){
    28         x=1;y=0;return a;
    29     }
    30     ll d=ex_gcd(b,a%b,y,x);
    31     y-=a/b*x;
    32     return d;
    33 }
    34 
    35 ll inv( ll a,ll n){
    36     return qpow(a,n-2,n);
    37 }
    38 
    39 ll getC(int m,int n){
    40     if(n>m) return 0;//2 2
    41     return F[m]*inv(F[n],MOD)%MOD*inv(F[m-n],MOD)%MOD;
    42 }
    43 
    44 int main(){
    45     init();
    46     int N,M;
    47     while(~scanf("%d%d",&N,&M)){
    48         ll a=getC(M+N-4,N-2);
    49         ll b=getC(M+N-4,N-1);
    50         ll c=getC(M+N-4,M-1);
    51         printf("%lld
    ",(a*a%MOD-b*c%MOD+MOD)%MOD);
    52     }
    53     return 0;
    54 }
    View Code

    I题

    直接dp会TLE,后来想切成M天内的小dp,各段再大DP,优化了一点但还是TLE

    正确做法应该用类似 矩阵快速幂 的方法 进行dp

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 typedef long long ll;
     5 
     6 ll mod=1e18;
     7 int N,M;
     8 struct Matrix{
     9     ll dat[101][101];
    10     struct Matrix operator * (struct Matrix &b)const {
    11         struct Matrix ret;
    12         for(int i=1;i<=M;++i)
    13             for(int j=1;j<=M;++j)
    14                 ret.dat[i][j]=0;
    15         for(int i=1;i<=M;++i)
    16             for(int j=1;j<=M;++j)
    17                 for(int k=1;k<=M;++k){
    18                     ret.dat[i][j]=max(ret.dat[i][j],this->dat[i][k]+b.dat[k][j]);
    19                 }
    20         return ret;
    21     }
    22 }stt;
    23 
    24 Matrix qPow(Matrix a,int n){
    25     Matrix ret;
    26     memset(ret.dat,0,sizeof(ret.dat));
    27     while(n){
    28         if(n&1) ret=ret*a;
    29         a=a*a;
    30         n>>=1;
    31     }
    32     return ret;
    33 }
    34 
    35 int main(){
    36     while(~scanf("%d%d",&N,&M)){
    37         for(int i=1;i<=M;++i)
    38             for(int j=1;j<=M;++j)
    39                 stt.dat[i][j]=0;
    40         for(int i=1;i<=M;++i)
    41             for(int j=1;j<=M;++j){
    42                 scanf("%lld",&stt.dat[i][j]);
    43             }
    44         Matrix fnl=qPow(stt,N-1);
    45         ll ans=-1ll; 
    46         for(int i=1;i<=M;++i)
    47             for(int j=1;j<=M;++j){
    48                 ans=max(ans,fnl.dat[i][j]);
    49             }
    50         printf("%lld
    ",ans);
    51     }
    52     return 0;
    53 }
    View Code

    To be continued !

  • 相关阅读:
    hyper虚拟机下对centos进行动态扩容
    《C#高级编程第七版》多线程之Events
    借鉴StanZhai核心代码,写了个博客园采集器
    文档转换之PDF转换为HTML
    书香电子书下载地址分析器
    c#常用类库及资源
    iis7.5 配置伪静态
    根据枚举类型获取描述
    从客户端检测到有潜在危险的Request.Form值
    Sql行列转换
  • 原文地址:https://www.cnblogs.com/Kiritsugu/p/9363613.html
Copyright © 2011-2022 走看看