zoukankan      html  css  js  c++  java
  • 测试 3

    T1
    30% 爆搜。
    20% 找c最小的,开始跳。
    20% 按h从小到大排序,顺序跳+枚举从哪座楼开始跳。
    100% 1.按照高度从低向高排序。n^2枚举最矮的楼和最高的楼是谁,
    然后对于中间的楼按c从小到大排序,然后顺序选就可以确定。
    复杂度 n^3*log(n)
    2。按照高度从小到大排序。f[i][j]表示我停在第i栋楼上,已
    经跳了j次楼的最小花费是几。
    状态转移方程:f[i][j+1]=min(f[i][j+1],f[k][j]+c[k]+abs(h[i]-h[k]));

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define N 51
    using namespace std;
    struct node{
        int c,h;
    }e[N];
    int n,t;
    int dp[N][N];
    bool cmp(node p,node q){
        return p.h<q.h;
    }
    int main(){
        freopen("meet.in","r",stdin);
        freopen("meet.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&e[i].c);
        for(int i=1;i<=n;i++) scanf("%d",&e[i].h);
        sort(e+1,e+n+1,cmp);
        memset(dp,63,sizeof(dp));
        for(int i=1;i<=n;i++) dp[0][i]=e[i].c;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++){
                for(int k=1;k<j;k++)
                    dp[i][j]=min(dp[i][j],dp[i-1][k]+e[j].h-e[k].h);
                dp[i][j]+=e[j].c;
            }
        scanf("%d",&t);
        for(int i=n;i>=0;i--)
            for(int j=1;j<=n;j++)
                if(dp[i][j]<=t){
                    printf("%d",i+1);
                    return 0;
                }
    }

     

    T2

    • 已知a1,a2,a3……an;
    • 已知b1,b2,b3……bn*(n-1)/2;
    1.  首先排序。
    2. 由题意得 a1+a2=b1;a1+a3=b2;a3=a2+b2-b1;
    3. 设a2+a3=x; 
    4. 可以解得:a1,a2,a3;
    5. 把a1+a2,a1+a3,a2+a3删去。
    6. 那么剩余的数中最小的一定是a1+a4。
    7. 然后a4可求。
    8. 然后删去a1+a4,a2+a4,a3+a4。
    9. 那么剩余的数中最小的一定是a1+a5。
    10. 然后a5可求。
    11. ……
    12. 剩下的问题就是如何确定a2+a3。
    13. 枚举a2+a3等于b3,b4……bn*(n-1)/2。
    14. 然后判断是否有可行的解即可。
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define MAXN  310 
    using namespace std;
    int n,m,cnt;
    int ans[MAXN][MAXN];
    bool use[MAXN*MAXN];
    int num[MAXN*MAXN],res[MAXN];
    void check(int now){
        memset(use,false,sizeof(use));
        if((num[1]+num[2]+num[now])&1)    return ;
        res[1]=(num[1]+num[2]+num[now])/2-num[now]; 
        res[2]=num[1]-res[1];
        res[3]=num[2]-res[1];
        use[1]=use[2]=use[now]=true;
        for(int i=4,j=3;i<=n;i++){
            while(j<=m&&use[j])    j++;
            if(j>m)    return ;
            res[i]=num[j]-res[1];
            use[j]=true;
            for(int k=2;k<i;k++){
                if(res[k]>res[i])    return ;
                int tmp=res[k]+res[i];
                int now=lower_bound(num+1,num+1+m,tmp)-num;
                if(num[now]!=tmp)    return ;
                int no=now;
                while(no&&num[no]==num[now])    no--;
                no++;
                while(no<=m&&num[no]==num[now]&&use[no])    no++;
                if(num[no]!=num[now]||use[no])    return ;
                now=no;
                use[now]=true;
            }
        }
        cnt++;
        for(int i=1;i<=n;i++)
            ans[cnt][i]=res[i];
    }
    int main(){
        freopen("city.in","r",stdin);
        freopen("city.out","w",stdout);
        scanf("%d",&n);
        m=n*(n-1)/2;
        for(int i=1;i<=m;i++)    scanf("%d",&num[i]);
        sort(num+1,num+1+m);
        for(int i=3;i<=m;){
            check(i);
            int j=i;
            while(j<=m&&num[j]==num[i])    j++;
            i=j;
        }
        cout<<cnt<<endl;
        for(int i=1;i<=cnt;i++){
            for(int j=1;j<=n;j++)
                cout<<ans[i][j]<<" ";
            cout<<endl;
        }
    }
    /*
    4
    11 17 21 12 20 15
    */

     

    T3
    30%暴力枚举可过。
    60% 1.首先全部mod p,记录下余数。然后用某种数据结构记录一下。
      然后每次查询时二分一下在这个l和r的位置,做差即为数的个数。
      空间复杂度O(n)。
    100% 对p分块。
      由60分思路考虑到对所有的p进行预处理。但是时间复杂度变为
      O(p*n),会TLE。
      所以想到分块。
        对于p<=100,套用60%的做法,对于每一个p预处理一遍。
        对于p>100的显然不能套用60%的做法。所以我们不去进行预处理。
        v+kp是%p等于v的情况。
        已知v+kp<=10000,p>100;
        所以k<=100
        对于所以每个%p最多只用计算100次。

    #include<vector> 
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define MAXN 100001
    using namespace std;
    vector<int>vec[10001];
    vector<int>ve[101][101];
    int n,m;
    int num[MAXN];
    int main(){
        freopen("light.in","r",stdin);
        freopen("light.out","w",stdout); 
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",&num[i]);
            vec[num[i]].push_back(i);
        } 
        for(int i=1;i<=100;i++)
            for(int j=1;j<=n;j++)
                ve[i][num[j]%i].push_back(j);
        while(m--){
            int l,r,p,v,L,R;
            scanf("%d%d%d%d",&l,&r,&p,&v);
            if(p<=100){
                L=0,R=ve[p][v].size()-1;
                int tmp1=-1,tmp2=-1;
                while(L<=R){
                    int mid=(L+R)/2;
                    if(ve[p][v][mid]>=l)    tmp1=mid,R=mid-1;
                    else L=mid+1;
                }
                if(tmp1==-1){ cout<<"0"<<endl;continue; }
                L=tmp1;R=ve[p][v].size()-1;
                while(L<=R){
                    int mid=(L+R)/2;
                    if(ve[p][v][mid]<=r)    tmp2=mid,L=mid+1;
                    else R=mid-1;
                }
                if(tmp2==-1){ cout<<"0"<<endl;continue; }
                cout<<tmp2-tmp1+1<<endl;
            }
            else{
                int pos=v,tot=0;
                while(pos<=10000){
                    L=0;R=vec[pos].size()-1;
                    int tmp1=-1,tmp2=-1;
                    while(L<=R){
                        int mid=(L+R)/2;
                        if(vec[pos][mid]>=l)    tmp1=mid,R=mid-1;
                        else L=mid+1;
                    }
                    if(tmp1==-1){ pos+=p;continue; }
                    L=tmp1;R=vec[pos].size()-1;
                    while(L<=R){
                        int mid=(L+R)/2;
                        if(vec[pos][mid]<=r)    tmp2=mid,L=mid+1;
                        else R=mid-1;
                    }
                    if(tmp2==-1){ pos+=p;continue; }
                    tot+=tmp2-tmp1+1;
                    pos+=p;
                }
                cout<<tot<<endl;
            }
        }
    }
    /*
    5 2
    1 5 2 3 7
    1 3 2 1
    2 5 3 0
    */
    细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。 雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。
  • 相关阅读:
    可遇不可求的Question之过滤单词字符的正则表达式\w的疑义
    可遇不可求的Question之DBNull.Value.ToString()
    可遇不可求的Question之MYSQL的10060和10061错误篇
    可遇不可求的Question之正在中止线程异常
    可遇不可求的Question之类型初始值设定项引发异常篇
    可遇不可求的Question之调用的目标发生了异常篇
    可遇不可求的Question之要复制的 LOB 数据的长度超出了配置的最大值篇
    熱海へ
    CC的留言
    研发才是硬道理钢铁侠的评论(摘自豆瓣)
  • 原文地址:https://www.cnblogs.com/cangT-Tlan/p/7787410.html
Copyright © 2011-2022 走看看