• 【NOIp】NOIp2011


    NOIp 2011

    Day1 T1  铺地毯

    标签:模拟

    code

     1 #include <cstdio>
     2 #include <cstdlib>
     3 using namespace std;
     4 int main()
     5 {
     6     int n,x,y,a[10001],b[10001],g[10001],k[10001];
     7     scanf("%d",&n);
     8     for(int i=1;i<=n;++i)
     9       scanf("%d %d %d %d",&a[i],&b[i],&g[i],&k[i]);
    10     scanf("%d %d",&x,&y);
    11     for(int i=n;i>=1;--i)
    12     if(x>=a[i]&&x<=a[i]+g[i]&&y>=b[i]&&y<=b[i]+k[i])
    13     {
    14         printf("%d
    ",i);
    15         exit(0);
    16     }
    17     printf("-1
    ");
    18     return 0;
    19 }
    T1

      

    Day1 T2 选择客栈

    标签:数据结构

    一看静态区间最小值,想到st表

    用st表维护区间内最小值是不是小于等于p,vector维护每种颜色的第i个在color数组中的位置

    code

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 namespace gengyf{
     4   inline int read(){
     5     int x=0,f=1;char s=getchar();
     6     while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
     7     while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
     8     return f*x;
     9   }
    10 #define ll long long
    11   const int maxn=2e5+10;
    12   int n,k,p,a[maxn][21],ans,x;
    13   vector<int>co[60];
    14   int query(int l,int r){
    15     int k=log2(r-l+1);
    16     return max(a[l][k],a[r-(1<<k)+1][k]);
    17   }
    18   int main(){
    19     n=read();k=read();p=read();
    20     for(int i=1;i<=n;i++){
    21       x=read();a[i][0]=(read()<=p)?1:0;
    22       co[x].push_back(i);
    23     }
    24     for(int j=1;j<=21;j++)
    25       for(int i=1;i+(1<<j)-1<=n;i++){
    26         a[i][j]=max(a[i][j-1],a[i+(1<<(j-1))][j-1]);
    27       }
    28     for(int t=0;t<k;t++){
    29       int i=0,j=1;
    30       for(;j<co[t].size();j++){
    31         if(query(co[t][j-1],co[t][j])){
    32           ans+=(ll)(co[t].size()-j)*(j-i);
    33           i=j;
    34         }
    35       }
    36     }
    37     printf("%d",ans);
    38     return 0;
    39   }
    40 }
    41 signed main(){
    42   gengyf::main();
    43   return 0;
    44 }
    T2

    Day1 T3 Manya游戏

    标签:模拟,搜索

    啥也不说了,考验码力的时候到了

    code

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 namespace gengyf{
      4 #define ll long long
      5   inline int read(){
      6     int x=0,f=1;char s=getchar();
      7     while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
      8     while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
      9     return f*x;
     10   }
     11   int n,map[10][10],ans[10][5],last[10][10][10],del[10][10];
     12   bool remove(){
     13     int flag=0;
     14     for(int i=1;i<=5;i++)
     15       for(int j=1;j<=7;j++){
     16         if(i-1>=1&&i+1<=5&&map[i][j]==map[i-1][j]&&map[i][j]==map[i+1][j]&&map[i][j]){
     17           del[i-1][j]=1;del[i+1][j]=1;del[i][j]=1;flag=1;
     18         }
     19         if(j-1>=1&&j+1<=7&&map[i][j]==map[i][j+1]&&map[i][j]==map[i][j-1]&&map[i][j]){
     20           del[i][j]=1;del[i][j+1]=1;del[i][j-1]=1;flag=1;
     21         }
     22       }
     23     if(!flag)return 0;
     24     for(int i=1;i<=5;i++)
     25       for(int j=1;j<=7;j++){
     26         if(del[i][j]){
     27           del[i][j]=0;
     28           map[i][j]=0;
     29         }
     30       }
     31     return 1;
     32   }
     33   bool check(){
     34     for(int i=1;i<=5;i++){
     35       if(map[i][1])return 0;
     36     }
     37     return 1;
     38   }
     39   void copy(int x){
     40     for(int i=1;i<=5;i++)
     41       for(int j=1;j<=7;j++){
     42         last[x][i][j]=map[i][j];
     43       }
     44   }
     45   void update(){
     46     for(int i=1;i<=5;i++){
     47       int tmp=0;
     48       for(int j=1;j<=7;j++){
     49         if(map[i][j]==0)tmp++;
     50         else {
     51           if(!tmp)continue;
     52           map[i][j-tmp]=map[i][j];
     53           map[i][j]=0;
     54         }
     55       }
     56     }
     57   }
     58   void move(int i,int j,int k){
     59     int tmp=map[i][j];
     60     map[i][j]=map[i+k][j];map[i+k][j]=tmp;
     61     update();
     62     while(remove())update();
     63   }
     64   void dfs(int x){
     65     if(check()){
     66       for(int i=1;i<=n;i++){
     67         if(i!=1)printf("
    ");
     68         for(int j=1;j<=3;j++){
     69           printf("%d ",ans[i][j]);
     70         }
     71       }
     72       exit(0);
     73     }
     74     if(x==n+1)return ;
     75     copy(x);
     76     for(int i=1;i<=5;i++)
     77       for(int j=1;j<=7;j++){
     78         if(map[i][j]){
     79           if(i+1<=5&&map[i][j]!=map[i+1][j]){
     80             move(i,j,1);
     81             ans[x][1]=i-1;ans[x][2]=j-1;ans[x][3]=1;
     82             dfs(x+1);
     83             for(int i=1;i<=5;i++)
     84               for(int j=1;j<=7;j++){
     85                 map[i][j]=last[x][i][j];
     86               }
     87             ans[x][1]=-1;ans[x][2]=-1;ans[x][3]=-1;
     88           }
     89         }
     90         if(i-1>=1&&map[i-1][j]==0){
     91           move(i,j,-1);
     92           ans[x][1]=i-1;ans[x][2]=j-1;ans[x][3]=-1;
     93           dfs(x+1);
     94           for(int i=1;i<=5;i++)
     95             for(int j=1;j<=7;j++){
     96               map[i][j]=last[x][i][j];
     97             }
     98           ans[x][1]=-1;ans[x][2]=-1;ans[x][3]=-1;
     99         }
    100       }
    101   }
    102   int main(){
    103     n=read();
    104     for(int i=1;i<=5;i++){
    105       for(int j=1;j<=8;j++){
    106         int x=read();
    107         if(x==0)break;
    108         map[i][j]=x;
    109       }
    110     }
    111     memset(ans,-1,sizeof(ans));
    112     dfs(1);
    113     printf("-1");
    114     return 0;
    115   }
    116 }
    117 signed main(){
    118   gengyf::main();
    119   return 0;
    120 }
    T3

    Day2 T1 计算系数

    标签:数论

    先看a=1,b=1的部分分

    n次方和的系数就是杨辉三角 -> 50pts

    再看100%数据

    拿出草稿纸一波推导->

    每一项的系数就是杨辉三角的值再乘(a^n)再乘(b^m),可以用快速幂实现

    code

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 namespace gengyf{
     4 #define int long long
     5   inline int read(){
     6     int x=0,f=1;char s=getchar();
     7     while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
     8     while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
     9     return f*x;
    10   }
    11   const int maxn=2001;
    12   const int mod=1e4+7;
    13   int a,b,k,m,n,f[maxn][maxn],ans;
    14   int qpow(int a,int b){
    15     int tmp=1,base=a;
    16     while(b){
    17       if(b&1)tmp=tmp*base%mod;
    18       base*=base;base%=mod;
    19       b>>=1;
    20     }
    21     return tmp;
    22   }
    23   int main(){
    24     scanf("%lld%lld%lld%lld%lld",&a,&b,&k,&n,&m);
    25     f[1][1]=1;
    26     for(int i=2;i<=k+1;i++)
    27       for(int j=1;j<=i;j++){
    28         f[i][j]=f[i-1][j-1]%mod+f[i-1][j]%mod;
    29         f[i][j]%=mod;
    30       }
    31     ans=f[k+1][k-n+1]%mod*qpow(a,n)*qpow(b,m)%mod;
    32     printf("%lld",ans);
    33     return 0;
    34   }
    35 }
    36 signed main(){
    37   gengyf::main();
    38   return 0;
    39 }
    T4

    Day2 T2 聪明的质检员

    标签:二分

    可以发现,W越大,能选的越少,W越小,能选的越多,满足二分性质

    Y的值为各个区间和,前缀和优化

    当w[i]>=W时会选上,这时数目的前缀和+1,价值的前缀和+v[i]

    code

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 namespace gengyf{
     4 #define int long long
     5   inline int read(){
     6     int x=0,f=1;char s=getchar();
     7     while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
     8     while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
     9     return f*x;
    10   }
    11   const int inf=2147483647;
    12   const int maxn=2e5+10;
    13   int n,m,s,maxx=-1,minn=inf;
    14   int pren[maxn],prev[maxn],w[maxn],v[maxn],l[maxn],r[maxn];
    15   int sum,y,ans=inf;
    16   bool check(int mid){
    17     sum=0;y=0;
    18     memset(pren,0,sizeof(pren));
    19     memset(prev,0,sizeof(prev));
    20     for(int i=1;i<=n;i++){
    21       if(w[i]>=mid){
    22         pren[i]=pren[i-1]+1;
    23         prev[i]=prev[i-1]+v[i];
    24       }
    25       else {
    26         pren[i]=pren[i-1];
    27         prev[i]=prev[i-1];
    28       }
    29     }
    30     for(int i=1;i<=m;i++){
    31       y+=(pren[r[i]]-pren[l[i]-1])*(prev[r[i]]-prev[l[i]-1]);
    32     }
    33     sum=llabs(y-s);
    34     if(y>s) return true;
    35     else return false;
    36   }
    37   int main(){
    38     n=read();m=read();s=read();
    39     for(int i=1;i<=n;i++){
    40       w[i]=read();v[i]=read();
    41       maxx=max(maxx,w[i]);
    42       minn=min(minn,w[i]);
    43     }
    44     for(int i=1;i<=m;i++){
    45       l[i]=read();r[i]=read();
    46     }
    47     int l=minn-1,r=maxx+2;
    48     ans=0x3f3f3f3f3f3f3f3f;
    49     while(l<=r){
    50       int mid=(l+r)>>1;
    51       if(check(mid)){
    52         l=mid+1;
    53       }
    54       else r=mid-1;
    55       if(sum<ans) ans=sum;
    56     }
    57     printf("%lld",ans);
    58     return 0;
    59   }
    60 }
    61 signed main(){
    62   gengyf::main();
    63   return 0;
    64 }
    T5

    Day2 T3 观光公交

    标签:贪心

    滴,您的智商余额不足,请充值~

    这题是在班会课上想明白的

    我们把每个乘客的上下车站点看成区间

    step 1:

    先考虑如果你只有一个加速器会放到哪

    肯定放在被覆盖次数最多的[i,i+1)

    step 2:

    如果只有一个人,在2号点上车,1号点和2号点的距离为1

    但这个人在第10分钟才来,你还是只有一个加速器,那完全可以不放对吧

    因为不管你放还是不放,都要等到第10分钟才能再出发往后开

    step 3:

    所以我们发现了贪心策略

    <1>找到被覆盖次数最多的那一段,放一个加速器

    <2>如果放了加速器之后还是需要等下一个站点到的人,就不放

    code(有注释)

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 namespace gengyf{
     4 #define ll long long
     5   inline int read(){
     6     int x=0,f=1;char s=getchar();
     7     while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
     8     while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
     9     return f*x;
    10   }
    11   const int maxn=1e3+10;
    12   const int maxm=1e4+10;
    13   int n,m,k,d[maxn],last[maxn],sum[maxm],ans;
    14   int f[maxn],maxx,g[maxn];
    15   //f[i]每个站点能影响的最远站点
    16   //last[i]最后一个人到i站的时间
    17   //g[i]车到i站点的最早时间
    18   struct node{
    19     int t,l,r;
    20   }a[maxm];
    21   void drive(int x){
    22     while(x--){
    23       f[n]=f[n-1]=n;
    24       int mark=0;maxx=-1;
    25       for(int i=n-2;i>=1;i--){
    26         if(g[i+1]<=last[i+1]){//如果需要等下一个乘客,影响+1
    27           f[i]=i+1;
    28         }
    29         else f[i]=f[i+1];
    30       }
    31       for(int i=1;i<=n-1;i++){
    32         int tmp=sum[f[i]]-sum[i];//最多影响的人数
    33         if(tmp>maxx&&d[i]>0){
    34           maxx=tmp;mark=i;//标记最需要减少时间的点
    35         }
    36       }
    37       ans-=maxx;d[mark]--;//更新装一个加速器后对答案和边的贡献
    38       for(int i=2;i<=n;i++){//更新
    39         g[i]=max(g[i-1],last[i-1])+d[i-1];
    40       }
    41     }
    42   }
    43   int main(){
    44     n=read();m=read();k=read();
    45     for(int i=1;i<=n-1;i++){
    46       d[i]=read();
    47     }
    48     for(int i=1;i<=m;i++){
    49       a[i].t=read();a[i].l=read();a[i].r=read();
    50     }
    51     for(int i=1;i<=m;i++){
    52       last[a[i].l]=max(last[a[i].l],a[i].t);//最后一个到该站点的时间
    53       sum[a[i].r]++;
    54     }
    55     g[1]=last[1];
    56     for(int i=1;i<=n;i++){
    57       sum[i]+=sum[i-1];//到该站点的总人数
    58     }
    59     for(int i=2;i<=n;i++){//车到i站点的最少时间
    60       g[i]=max(g[i-1],last[i-1])+d[i-1];
    61     }
    62     for(int i=1;i<=m;i++){
    63       ans+=g[a[i].r]-a[i].t;//不需要加速器的答案
    64     }
    65     drive(k);
    66     printf("%d",ans);
    67     return 0;
    68   }
    69 }
    70 signed main(){
    71   gengyf::main();
    72   return 0;
    73 }
    T6

    6道题的NOIp就是没有4道的好写啊

  • 相关阅读:
    数据结构与算法分析-二叉堆
    数据结构与算法分析-AVL树
    数据结构与算法分析-二叉查找树
    优秀程序员应具备的15个特性
    2016年1月22日 收盘后美加的走势
    2016年1月8日 12月非农数据
    Replace into 与Insert into on duplicate key update的区别
    MYSQL视图的学习笔记
    postgresql创建用户
    连接postgresql数据库
  • 原文地址:https://www.cnblogs.com/gengyf/p/11529231.html
Copyright © 2020-2023  润新知