zoukankan      html  css  js  c++  java
  • 20160729noip模拟赛zld

    image

    首先显然有多少个奇数,就有多少个回文串是最优的(没有奇数时构造一个回文串

    然后有了k个“核心”,把剩下的字符顺序安排到这些的两侧,最后最短的回文串长度就是答案

    #include<map>
    #include<stack>
    #include<queue>
    #include<cstdio>
    #include<string>
    #include<vector>
    #include<cstring>
    #include<complex>
    #include<iostream>
    #include<assert.h>
    #include<algorithm>
    using namespace std;
    #define inf 1001001001
    #define infll 1001001001001001001LL
    #define FOR(i,a,n) for(int (i)=a;(i)<=(n);++(i))
    #define FOR1(i,n) for(int (i)=1;(i)<=(n);++(i))
    #define ll long long
    #define dbg(vari) cerr<<#vari<<" = "<<(vari)<<endl
    #define gmax(a,b) (a)=max((a),(b))
    #define gmin(a,b) (a)=min((a),(b))
    #define ios0 ios_base::sync_with_stdio(0)
    #define Ri register int
    #define gc getchar()
    #define il inline
    il int read(){
        bool f=true;
        Ri x=0;char ch;
        while(!isdigit(ch=gc))if(ch=='-')f=false;
        while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=gc;}
        return f?x:-x;
    }
    #define gi read()
    #define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
    int n,a[100005];
    int main(){
        FO(palindromic);
        int T=gi;
        while(T--){
            int cnt=0,sum=0;
            n=gi;    
            FOR1(i,n){
                a[i]=gi;sum+=a[i]; 
                if(a[i]&1)cnt++;
            }
    //        printf("%d %d
    ",cnt,sum);
            if(cnt)
            cout<<(sum-cnt)/2/cnt*2+1<<endl; 
            else cout<<sum<<endl;
        } 
        return 0;
    }

    image

    上次做这题:20160430ysy出题的时候

    首先任意两点的最短路只有两种情况:曼哈顿距离,曼哈顿距离+2

    那么我们考虑怎样的点对曼哈顿距离会被影响

    显然是下面这样的:黑色是障碍,红色和蓝点距离加2

    image

    那么我们分行列统计这样的对数,就可以(

    //fyb
    //旅行 
    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    typedef double ll;
    ll tot;
    ll gg;
    int n,m;
    char s[2000];
    int row[1010],col[1010];
    int fyb(int i,int j,int k){return 2*(i-1)*(k-j);}
    ll dorow(){
        ll ans=0;
        for(int i=1;i<n;i++)
            for(int j=i+1;j<=n;j++)
                ans=ans+(m-(row[i]>0))*(m-(row[j]>0))*(j-i)/gg;
        for (int i=1;i<=n;i++)
            if (row[i]){
                ans=ans+fyb(row[i],row[i],m)/gg;
                for(int j=i-1;j>0&&row[j]&&row[j]<row[j+1];j--)    ans=ans + fyb(row[j],row[i],m)/gg;
                for(int j=i+1;j<=n&&row[j]&&row[j]<row[j-1];j++)ans=ans + fyb(row[j],row[i],m)/gg;                                                                
            }
        return ans;
    }
    ll docol(){
        ll ans=0;
        for (int i=1;i<m;i++)
            for (int j=i+1;j<=m;j++)
                ans=ans+(n-(col[i]>0))*(n-(col[j]>0))*(j-i)/gg;
        for (int i=1;i<=m;i++)
            if (col[i]){
                ans=ans+fyb(col[i],col[i],n)/gg;
                for(int j=i-1;j>0&&col[j]&&col[j]<col[j+1];j--) ans= ans + fyb(col[j],col[i],n)/gg;                                        
                for(int j=i+1;j<=m&&col[j]&&col[j]<col[j-1];j++) ans=ans + fyb(col[j],col[i],n)/gg;                                        
            }    
        return ans;
    }
    int main(){
        freopen("chess.in","r",stdin);
        freopen("chess.out","w",stdout); 
        int T;
        scanf("%d",&T);
        while(T--){
            scanf("%d%d",&n,&m);
            tot=0;memset(row,0,sizeof(row));memset(col,0,sizeof(col));
            for (int i=1;i<=n;i++){
                scanf("%s",s);
                for (int j=0;j<m;j++) 
                    if (s[j]=='G'){
                        tot++;
                        row[i]=j+1;
                        col[j+1]=i;
                        break;
                    }        
            }
            gg=n*m-tot;
            gg = gg * gg;
            double gg2 = dorow() + docol();
            gg2 = gg2 * 2.0;
            printf("%.4lf
    ", gg2);
        }
        return 0;
    }

    (出现了玄学的换行

    image

    设定ans[i][j]

    表示当前时刻,从i-j最早什么时候到达

    首先我们发现,加上一条边只会影响这条边的起点出发的边和到达终点的边

    那么我们反向加边,每次更新一些ans[i][j]

    查询就变得简洁很多了。

    #include<map>
    #include<stack>
    #include<queue>
    #include<cstdio>
    #include<string>
    #include<vector>
    #include<cstring>
    #include<complex>
    #include<iostream>
    #include<assert.h>
    #include<algorithm>
    using namespace std;
    #define inf 1001001001
    #define infll 1001001001001001001LL
    #define FOR0(i,n) for(int (i)=0;(i)<(n);++(i))
    #define FOR1(i,n) for(int (i)=1;(i)<=(n);++(i))
    #define ll long long
    #define dbg(vari) cerr<<#vari<<" = "<<(vari)<<endl
    #define gmax(a,b) (a)=max((a),(b))
    #define gmin(a,b) (a)=min((a),(b))
    #define ios0 ios_base::sync_with_stdio(0)
    #define Ri register int
    #define gc getchar()
    #define il inline
    il int read(){
        bool f=true;
        Ri x=0;char ch;
        while(!isdigit(ch=gc))if(ch=='-')f=false;
        while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=gc;}
        return f?x:-x;
    }
    #define gi read()
    #define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
    int n,m,q,u[233333],v[233333],ans[233333];
    struct data{
        int a,b,c,d,id;
        void input(){
            a=gi;b=gi;c=gi;d=gi;
        }
    }a[233333];
    bool operator<(data a,data b){
        return a.a<b.a;
    }
    int dis[2333][2333];
    int main(){
        FO(plan);
        n=gi;m=gi;q=gi;
        memset(dis,127/3,sizeof(dis));
        FOR1(i,n)    dis[i][i]=0;
        FOR1(i,m)    u[i]=gi,v[i]=gi;
        FOR1(i,q)    a[i].input(),a[i].id=i;
        sort(a+1,a+q+1);
        int t=q;
        for(int i=m;i>=1;i--){
            dis[u[i]][v[i]]=dis[v[i]][u[i]]=i;
            for(int j=1;j<=n;j++)    dis[u[i]][j]=min(dis[u[i]][j],max(dis[v[i]][j],i));
            for(int j=1;j<=n;j++)    dis[v[i]][j]=min(dis[v[i]][j],max(dis[u[i]][j],i));
            while(t&&a[t].a==i){
                if(dis[a[t].c][a[t].d]<=a[t].b)ans[a[t].id]=true;
                --t;
            }
        }
        for(int i=1;i<=q;i++) if(ans[i]) puts("Yes"); else puts("No");
    }
  • 相关阅读:
    Python引入pandas报错ValueError: numpy.ufunc has the wrong size, try recompiling
    Oracle TNS无法解析ORA-12154报错
    python两个一维list列表合并
    SQL数据表加索引CREATE INDEX
    Python 格式化输出
    Python中三个双引号的作用
    2.认识素描
    如何快速学习Tableau Desktop
    1.怎样学习素描
    正点原子嵌入式Linux笔记3——Ubuntu软件安装
  • 原文地址:https://www.cnblogs.com/chouti/p/5729192.html
Copyright © 2011-2022 走看看