zoukankan      html  css  js  c++  java
  • NOIP2014-6-14模拟赛

    Problem 1 抓牛(catchcow.cpp/c/pas)

    【题目描述】

           农夫约翰被通知,他的一只奶牛逃逸了!所以他决定,马上出发,尽快把那只奶牛抓回来.

    他们都站在数轴上.约翰在N(O≤N≤100000)处,奶牛在K(O≤K≤100000)处.约翰有两种办法移动,步行和瞬移:步行每秒种可以让约翰从x处走到x+l或x-l处;而瞬移则可让他在1秒内从x处消失,在2x处出现.然而那只逃逸的奶牛,悲剧地没有发现自己的处境多么糟糕,正站在那儿一动不动.

           那么,约翰需要多少时间抓住那只牛呢?

    【输入格式】

    仅有两个整数N和K

    【输出格式】

    最短时间

    【样例输入】

    5 17

    【样例输出】

    4

    Problem 2 路面修整(grading.cpp/c/pas)

    【题目描述】

    FJ打算好好修一下农场中某条凹凸不平的土路。按奶牛们的要求,修好后的路面高度应当单调上升或单调下降,也就是说,高度上升与高度下降的路段不能同时出现在修好的路中。 整条路被分成了N段,N个整数A_1, ... , A_N (1 <= N <= 2,000)依次描述了每一段路的高度(0 <= A_i <= 1,000,000,000)。FJ希望找到一个恰好含N个元素的不上升或不下降序列B_1, ... , B_N,作为修过的路中每个路段的高度。由于将每一段路垫高或挖低一个单位的花费相同,修路的总支出可以表示为: |A_1 - B_1| + |A_2 - B_2| + ... + |A_N - B_N| 请你计算一下,FJ在这项工程上的最小支出是多少。FJ向你保证,这个支出不会超过2^31-1。【输入格式】
     第1行: 输入1个整数:N * 第2..N+1行: 第i+1行为1个整数:A_i

    【输出格式】
    第1行: 输出1个正整数,表示FJ把路修成高度不上升或高度不下降的最小花费

    【样例输入】

    7
    1
    3
    2
    4
    5
    3
    9

    【样例输出】

    3

    【样例解释】

    FJ将第一个高度为3的路段的高度减少为2,将第二个高度为3的路段的高度增加到5,总花费为|2-3|+|5-3| = 3,并且各路段的高度为一个不下降序列 1,2,2,4,5,5,9。

    Problem 3 教主的魔法(magic.cpp/c/pas)

    【题目描述】

    教主最近学会了一种神奇的魔法,能够使人长高。于是他准备演示给XMYZ信息组每个英雄看。于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1、2、……、N。

    每个人的身高一开始都是不超过1000的正整数。教主的魔法每次可以把闭区间[L, R](1≤L≤R≤N)内的英雄的身高全部加上一个整数W。(虽然L=R时并不符合区间的书写规范,但我们可以认为是单独增加第L(R)个英雄的身高)

    CYZ、光哥和ZJQ等人不信教主的邪,于是他们有时候会问WD闭区间 [L, R] 内有多少英雄身高大于等于C,以验证教主的魔法是否真的有效。

    WD巨懒,于是他把这个回答的任务交给了你。

    【输入格式】

     第1行为两个整数N、Q。Q为问题数与教主的施法数总和。

     第2行有N个正整数,第i个数代表第i个英雄的身高。

     第3到第Q+2行每行有一个操作:

    (1)若第一个字母为“M”,则紧接着有三个数字L、R、W。表示对闭区间 [L, R] 内所有英雄的身高加上W。

    (2)若第一个字母为“A”,则紧接着有三个数字L、R、C。询问闭区间 [L, R] 内有多少英雄的身高大于等于C。

    【输出格式】

         对每个“A”询问输出一行,仅含一个整数,表示闭区间 [L, R] 内身高大于等于C的英雄数。

     【样例输入】

    5 3

    1 2 3 4 5

    A 1 5 4

    M 3 5 1

    A 1 5 4

    【样例输出】

    2

    3

    【数据范围】

    【输入输出样例说明】

    原先5个英雄身高为1、2、3、4、5,此时[1, 5]间有2个英雄的身高大于等于4。教主施法后变为1、2、4、5、6,此时[1, 5]间有3个英雄的身高大于等于4。

    【数据范围】

    对30%的数据,N≤1000,Q≤1000。

    对100%的数据,N≤1000000,Q≤3000,1≤W≤1000,1≤C≤1,000,000,000

    Problem 4 吃豆豆(pacman.cpp/c/pas)

    【问题描述】

             两个PACMAN吃豆豆。一开始的时候,PACMAN都在坐标原点的左下方,豆豆都在右上方。PACMAN走到豆豆处就会吃掉它。PACMAN行走的路线很奇怪,只能向右走或者向上走,他们行走的路线不可以相交。

             请你帮这两个PACMAN计算一下,他们两加起来最多能吃掉多少豆豆。

    【输入文件】

             第一行为一个整数N,表示豆豆的数目。接下来N行,每行一对正整数Xi,Yi,表示第i个豆豆的坐标。任意两个豆豆的坐标都不会重合。

    【输出文件】

             仅有一行包含一个整数,即两个PACMAN加起来最多能吃掉的豆豆数量。

    【输入样例】

    8

    8  1

    1  5

    5  7

    2  2

    7  8

    4  6

    3  3

    6  4

    【输出样例】

    7

    【数据规模】

    对于30%的数据,1<=N<=25;

    对于70%的数据,1<=N<=500;

    对于100%的数据,1<=N<=2000,1<=Xi ,Yi <=200000  ;


    T1:

    宽搜妥妥的,注意queue数组开3倍

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<algorithm>
     4 #include<cstring>
     5 #define MAXN 100005 
     6 using namespace std;
     7 int b[MAXN];
     8 int n,k;
     9 int qL[3*MAXN],qM[3*MAXN],L=1,R;
    10 void bfs(){
    11     qL[++R]=n;
    12     qM[R]=0;
    13     while(L<=R){
    14         int x=qL[L],p=qM[L];
    15         if(x==k){
    16             return;
    17         }
    18         L++;
    19         int dx=x+1;
    20         if(0<=dx&&dx<MAXN&&!b[dx]){
    21             b[dx]=p+1;
    22             qL[++R]=dx;
    23             qM[R]=b[dx];
    24         }
    25         dx=x-1;
    26         if(0<=dx&&dx<MAXN&&!b[dx]){
    27             b[dx]=p+1;
    28             qL[++R]=dx;
    29             qM[R]=b[dx];
    30         }
    31         dx=x*2;
    32         if(0<=dx&&dx<MAXN&&!b[dx]){
    33             b[dx]=p+1;
    34             qL[++R]=dx;
    35             qM[R]=b[dx];
    36         }
    37     }
    38 }
    39 int main()
    40 {
    41 //    freopen("data.in","r",stdin);
    42     scanf("%d%d",&n,&k);
    43     bfs();
    44     printf("%d
    ",b[k]);
    45     return 0;
    46 }
    Code1

    T2:

    离散化+dp

    将高度离散化,f[i][j]表示前i个路段解决,且最后一个路段高度为s[j]的状态(s[j]表示从小到大排序后第j个)

    则有f[1][j]=Abs(s[j]-a[1])

    f[i][j]=min{f[i-1][k] | 1<=k<=j } + Abs(s[j]-a[i])

    把min记录下来边dp边更新O(1)

    上面的方程是递增的,递减类似

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<algorithm>
     4 #include<cstring>
     5 #define MAXN 2005
     6 #define ll long long
     7 using namespace std;
     8 int a[MAXN];
     9 int s[MAXN];
    10 ll f[MAXN][MAXN];
    11 int n;
    12 int Abs(int x){
    13     return (x>0)?x:-x;
    14 }
    15 int read(){
    16     int x=0,f=1;char ch=getchar();
    17     while(ch<'0'||ch>'9'){if('-'==ch)f=-1;ch=getchar();}
    18     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    19     return x*f;
    20 }
    21 int main()
    22 {
    23     n=read();
    24     for(int i=1;i<=n;i++){
    25         s[i]=a[i]=read();
    26     }
    27     sort(s+1,s+n+1);
    28     for(int i=1;i<=n;i++){
    29         f[1][i]=Abs(s[i]-a[1]);
    30     }
    31     for(int i=2;i<=n;i++){
    32         ll t=f[i-1][1];
    33         for(int j=1;j<=n;j++){
    34             t=min(t,f[i-1][j]);
    35             f[i][j]=t+Abs(s[j]-a[i]);
    36         }    
    37     }
    38     ll ans=f[n][1];
    39     for(int i=2;i<=n;i++){
    40         ans=min(ans,f[n][i]);
    41     }
    42 //    printf("%lld
    ",ans);
    43     for(int i=2;i<=n;i++){
    44         ll t=f[i-1][n];
    45         for(int j=n;j>=1;j--){
    46             t=min(t,f[i-1][j]);
    47             f[i][j]=t+Abs(s[j]-a[i]);
    48         }    
    49     }
    50     for(int i=1;i<=n;i++){
    51         ans=min(ans,f[n][i]);
    52     }
    53     printf("%lld
    ",ans);
    54     return 0;
    55 }
    Code2

    T3:

    平方分割

    顺便写下注意事项:

    1,桶中保存两个数组,一个是原数组,一个是排序后的数组,不可搞混了

    2,对于第i个元素,相应的桶编号为i/L,相应桶中的编号为i%L,前提都是从0开始计算

    3,对于处理,先讨论是不是在一个桶中,如果是一个桶直接L到R即可。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cmath>
      6 #define SIZE 1005
      7 #define MAXN 1000005
      8 #define ll long long
      9 using namespace std;
     10 struct Bucket{
     11     int len;
     12     ll a[SIZE];
     13     ll b[SIZE];
     14     ll tag;
     15     Bucket(){
     16         len=-1;
     17         tag=0;
     18         memset(a,0,sizeof(a));
     19         memset(b,0,sizeof(b));
     20     }
     21     void insert(ll x){
     22         a[++len]=x;
     23     }
     24     void update(){
     25         memcpy(b,a,sizeof(b));
     26         sort(b,b+len+1);
     27     }
     28     void Left_Add(int L,ll x){
     29         for(int i=L;i<=len;i++){
     30             a[i]+=x;
     31         }
     32         update();
     33     }
     34     void Right_Add(int R,ll x){
     35         for(int i=0;i<=R;i++){
     36             a[i]+=x;
     37         }
     38         update();
     39     }
     40     void Add(int L,int R,ll x){
     41         for(int i=L;i<=R;i++){
     42             a[i]+=x;
     43         }
     44         update();
     45     }
     46     void All_Add(ll x){
     47         tag+=x;
     48     }
     49     int Left_Ask(int L,ll x){
     50         x-=tag;
     51         int ret=0;
     52         for(int i=L;i<=len;i++){
     53             if(a[i]>=x){
     54                 ret++;
     55             }
     56         }
     57         return ret;
     58     }
     59     int Right_Ask(int R,ll x){
     60         x-=tag;
     61         int ret=0;
     62         for(int i=0;i<=R;i++){
     63             if(a[i]>=x){
     64                 ret++;
     65             }
     66         }
     67         return ret;
     68     }
     69     int All_Ask(ll x){
     70         x-=tag;
     71         int Pos=lower_bound(b,b+len+1,x)-b;
     72         return len-Pos+1;
     73     }
     74     int Ask(int L,int R,ll x){
     75         tag-=x;
     76         int ret=0;
     77         for(int i=L;i<=R;i++){
     78             if(a[i]>=x){
     79                 ret++;
     80             }
     81         }
     82         return ret;
     83     }
     84 }S[SIZE];
     85 ll read(){
     86     ll x=0,f=1;char ch=getchar();
     87     while(ch<'0'||ch>'9'){if('-'==ch)f=-1;ch=getchar();}
     88     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     89     return x*f;
     90 }
     91 int n,L;
     92 int pos[MAXN];
     93 int main()
     94 {
     95 //    freopen("magic.in","r",stdin);
     96 //    freopen("magic.out","w",stdout);
     97     int T;
     98     scanf("%d%d",&n,&T);
     99     L=sqrt(n);
    100     for(int i=0;i<n;i++){
    101         ll t;
    102         scanf("%lld",&t);
    103         S[i/L].insert(t);
    104         pos[i]=i%L;
    105     }
    106     for(int i=0;i<=(n-1)/L;i++){
    107         S[i].update();
    108     }
    109     for(int i=1;i<=T;i++){
    110         char ch[5];
    111         int s,t;ll x;
    112         scanf("%s%d%d%lld",ch,&s,&t,&x);
    113         s--;t--;
    114         int sx=s/L,tx=t/L;
    115         if(sx!=tx){
    116             if('M'==ch[0]){
    117                 S[sx].Left_Add(pos[s],x);
    118                 S[tx].Right_Add(pos[t],x);
    119                 for(int j=sx+1;j<tx;j++){
    120                     S[j].All_Add(x);
    121                 }
    122             }    
    123             else{
    124                 int ans=0;
    125                 ans+=S[sx].Left_Ask(pos[s],x);
    126                 ans+=S[tx].Right_Ask(pos[t],x);
    127                 for(int j=sx+1;j<tx;j++){
    128                     ans+=S[j].All_Ask(x);
    129                 }
    130                 printf("%d
    ",ans);
    131             }        
    132         }
    133         else{
    134             if('M'==ch[0]){
    135                 S[sx].Add(pos[s],pos[t],x);
    136             }    
    137             else{
    138                 int ans=0;
    139                 ans+=S[sx].Ask(pos[s],pos[t],x);
    140                 printf("%d
    ",ans);
    141             }                
    142         }
    143     }
    144     return 0;
    145 }
    Code3

    T4:

    先玩个dp骗骗分 40分

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<ctime>
     6 #include<iostream>
     7 #define MAXN 205
     8 #define pii pair<int,int>
     9 using namespace std;
    10 int n;
    11 int X[MAXN],Y[MAXN];
    12 int S[MAXN][MAXN];
    13 int mx,my;
    14 int dp[MAXN+MAXN][MAXN][MAXN];
    15 int go[2]={0,-1};
    16 pii a[MAXN];
    17 void LiSan(){
    18     
    19     for(int i=1;i<=n;i++){
    20         a[i]=make_pair(X[i],i);
    21     }
    22     sort(a+1,a+n+1);
    23     for(int i=1;i<=n;i++){
    24         if(a[i-1].first!=a[i].first) mx++;
    25         X[a[i].second]=mx;
    26     }
    27     for(int i=1;i<=n;i++){
    28         a[i]=make_pair(Y[i],i);
    29     }
    30     sort(a+1,a+n+1);
    31     for(int i=1;i<=n;i++){
    32         if(a[i-1].first!=a[i].first) my++;
    33         Y[a[i].second]=my;
    34     }
    35 //    for(int i=1;i<=n;i++){
    36 //        printf("%d %d
    ",X[i],Y[i]);
    37 //    }
    38     for(int i=1;i<=n;i++){
    39         S[X[i]][Y[i]]=1;
    40     }
    41 }
    42 int read(){
    43     int x=0,f=1;char ch=getchar();
    44     while(ch<'0'||ch>'9'){if('-'==ch)f=-1;ch=getchar();}
    45     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    46     return x*f;
    47 }
    48 int main()
    49 {
    50 //    double begin,end;
    51 //    begin=clock();
    52 //    freopen("pacman1.in","r",stdin);
    53 //    freopen("data.out","w",stdout);
    54     n=read();
    55     for(int i=1;i<=n;i++){
    56         X[i]=read();
    57         Y[i]=read();
    58     }
    59     LiSan();
    60 //    for(int i=1;i<=mx;i++){
    61 //        for(int j=1;j<=my;j++){
    62 //            printf("%d ",S[i][j]);
    63 //        }
    64 //        printf("
    ");
    65 //    }
    66     dp[3][1][2]=S[1][1]+S[1][2]+S[2][1];
    67     for(int s=4;s<=mx+my-1;s++){
    68         for(int i=1;i<=min(mx,s-1);i++){
    69             for(int j=i+1;j<=min(mx,s-1);j++){
    70                 for(int k=0;k<2;k++){
    71                     int x1=i+go[k];
    72                     int y1=s-1-x1;
    73                     for(int l=0;l<2;l++){
    74                         int x2=j+go[l];
    75                         int y2=s-1-x2;
    76                         if(x1==x2&&y1==y2){
    77                             continue;
    78                         }
    79                         dp[s][i][j]=max(dp[s][i][j],dp[s-1][x1][x2]);
    80                     }
    81                 }
    82                 dp[s][i][j]+=S[i][s-i];
    83                 dp[s][i][j]+=S[j][s-j];
    84             }
    85         }
    86     }
    87     printf("%d
    ",dp[mx+my-1][mx-1][mx]+S[mx][my]);
    88 //    end=clock();
    89 //    printf("%f
    ",(end-begin)/CLOCK_PER_SEC);
    90     return 0;
    91 }
    Code3

    正解是费用流NOIP不考不管啦QAQ

  • 相关阅读:
    javascript闭包和作用域链
    关于git的简单实用命令
    springMVC配置Json
    Python基础教程(010)--第一个程序Hello Python
    Python基础教程(009)--Python程序的格式以及扩展名
    Python基础教程(008)--第一个Python程序
    Python基础教程(007)--Python的优缺点
    Python基础教程(006)--Python的特点
    Python基础教程(005)--为什么要学习Python?
    Python基础教程(004)--Python的设计哲学
  • 原文地址:https://www.cnblogs.com/w-h-h/p/7631691.html
Copyright © 2011-2022 走看看