• 【NOIP2012】提高组


    Day1

    T1vigenere密码

    题目链接

    vijos截得不全导致题意可能会理解错,注意小写字母应该是先转大写进行变换,再根据情况看是否需要再转成小写。

    然后,然后就没了啊。

     1 #include<cstdio>
     2 #include<cstring>
     3 char ch[105],tt[1005],an[1005];
     4 int len,le,mi[105];
     5 int main(){
     6     scanf("%s %s",ch+1,tt+1);
     7     len=strlen(ch+1);le=strlen(tt+1);
     8     for(int i=1;i<=len;i++){
     9         if(ch[i]>='a')ch[i]=ch[i]-('a'-'A');
    10         mi[i]=ch[i]-130;
    11     }
    12     int h=1;
    13     for(int i=1;i<=le;i++,h++){
    14         if(h>len)h=1;
    15         int p=tt[i]>='a'?tt[i]-('a'-'A'):tt[i];
    16         p-=65;
    17         for(int x='A';x<='Z';x++)if((x+mi[h])%26==p){an[i]=x;break;}
    18         if(tt[i]>='a')an[i]+='a'-'A';
    19     }
    20     for(int i=1;i<=le;i++)printf("%c",an[i]);
    21     return 0;
    22 }
    D1 T1

    T2国王游戏

    题目链接

    对于两个人的顺序安排,不会对前后的其他人造成影响。

    设两个人左右手上数字分别为l1,r1;l2,r2。

    那么答案就是min(max(l1/r2,1/r1),max(l2/r1,1/r2))。-->忽略前面的数,反正也会被约掉

    1.当r1>r2时:

      l1/r2>1/r1;l1/r2>1/r2;

    所以答案是min(l1/r2,l2/r1)。

    2.当r2>r1时:

      l2/r1>1/r2;l2/r1>1/r1;

    所以答案tm还是min(l1/r2,l2/r1)。

    综上答案只跟l1/r2和l2/r1的大小的关系有关。

    交叉相乘得:

    当l1*r1>l2*r2时,l1/r2>l2/r1;否则l1/r2<l2/r1。

    那么只要按l*r从小到大排个序就好啦。

    对了好像还有个高精乘低精和高精除低精......

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<queue>
     5 #include<cmath>
     6 typedef long long LL;
     7 const int N=1005;
     8 int read(){
     9     int ans=0,f=1;char c=getchar();
    10     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    11     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
    12     return ans*f;
    13 }
    14 struct node{
    15     LL li,ri,wi;
    16     bool operator <(const node&p)const{return p.wi<wi;}
    17 };
    18 std::priority_queue<node>q;
    19 LL mxa[5000],ch[5000],y[5000];
    20 void mul(LL x[],LL d){
    21     LL jin=0,wei=log(d)/log(10)+1;
    22     x[0]+=wei;
    23     for(int i=1;i<=x[0];i++){
    24         x[i]=x[i]*d+jin;
    25         jin=x[i]/10;
    26         x[i]%=10;
    27     }
    28     while(x[x[0]]==0)x[0]--;
    29 }
    30 void mol(LL x[],LL d){
    31     LL sh=0;
    32     for(int i=x[0];i>=1;i--){
    33         sh=sh*10+x[i];
    34         x[i]=sh/d;
    35         sh=sh%d;
    36     }
    37     while(x[x[0]]==0)x[0]--;
    38 }
    39 void max(){
    40     if(y[0]<mxa[0])return;
    41     if(mxa[0]<y[0]){memcpy(mxa,y,sizeof(mxa));return;}
    42     for(int i=mxa[0];i>=1;i--)
    43         if(y[i]>mxa[i]){memcpy(mxa,y,sizeof(mxa));return;}
    44 }
    45 int main(){
    46     int n=read();
    47     LL op=read();read();
    48     while(op)ch[++ch[0]]=op%10,op/=10;
    49     for(int i=1,a,b;i<=n;i++){
    50         a=read();b=read();
    51         q.push((node){a,b,a*b});
    52     }
    53     for(int i=1;i<=n;i++){
    54         node p=q.top();q.pop();
    55         for(int i=0;i<=ch[0];i++)y[i]=ch[i];
    56         mol(y,p.ri);
    57         max();
    58         mul(ch,p.li);
    59     }
    60     for(int i=mxa[0];i>=1;i--)printf("%lld",mxa[i]);
    61     return 0;
    62 }
    D1 T2

    T3开车旅行

    题目链接

    从后往前预处理出离每个点的最近、次近距离(平衡树),那么第一第二问就都是一个倍增可以解决的东西了。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<set>
     5 #define mem(a,p) memset(a,p,sizeof(a))
     6 typedef long long LL;
     7 const int N=1e5+10;
     8 struct node{
     9     int hi,id;
    10     bool operator <(const node&p)const{return p.hi>hi;}
    11 };
    12 struct no{int hi,yu,id;};
    13 bool cmp(no a,no b){return a.hi!=b.hi?a.hi<b.hi:a.yu<b.yu;}
    14 int n,h[N],m;
    15 typedef std::multiset<node>myset;
    16 typedef myset::iterator IT;
    17 myset se;
    18 LL ato[N][22],bto[N][22];
    19 int g[N][22],to[N],co[N];
    20 int read(){
    21     int ans=0,f=1;char c=getchar();
    22     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    23     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
    24     return ans*f;
    25 }
    26 int main(){
    27     n=read();
    28     for(int i=1;i<=n;i++)h[i]=read();
    29     se.insert((node){h[n],n});se.insert((node){h[n-1],n-1});
    30     bto[n-1][0]=abs(h[n]-h[n-1]);to[n-1]=n;
    31     for(int i=0;i<=n;i++)
    32         for(int j=0;j<=20;j++)ato[i][j]=bto[i][j]=2e9;
    33     for(int i=n-2;i>=1;i--){
    34         IT it=se.lower_bound((node){h[i],i});
    35         IT it0=it;
    36         no q[5];int tot=0;
    37         if(it!=se.end()){
    38             q[++tot]=(no){abs(it->hi-h[i]),it->hi,it->id};
    39             it++;
    40             if(it!=se.end())q[++tot]=(no){abs(it->hi-h[i]),it->hi,it->id};
    41         }
    42         if(it0!=se.begin()){
    43             it0--;q[++tot]=(no){abs(h[i]-it0->hi),it0->hi,it0->id};
    44             if(it0!=se.begin())it0--,q[++tot]=(no){abs(h[i]-it0->hi),it0->hi,it0->id};
    45         }
    46         se.insert((node){h[i],i});
    47         if(tot<=1)continue;
    48         std::sort(q+1,q+1+tot,cmp);
    49         ato[i][0]=q[2].hi;to[i]=q[1].id;g[i][0]=q[2].id;co[i]=q[2].id;
    50         if(to[q[2].id])bto[i][0]=abs(h[to[q[2].id]]-h[q[2].id]),g[i][0]=to[q[2].id];
    51     }
    52     for(int i=n;i>=1;i--){
    53         for(int j=1;i+(1<<j)<=n;j++){
    54             g[i][j]=g[g[i][j-1]][j-1];
    55             ato[i][j]=ato[i][j-1]+ato[g[i][j-1]][j-1];
    56             bto[i][j]=bto[i][j-1]+bto[g[i][j-1]][j-1];
    57         }
    58     }
    59     int x0=read();double mni=2e9;int id=0;
    60     for(int i=1;i<=n;i++){
    61         LL sa=0,sb=0;int i0=i,xx=x0;
    62         bool fl=0;
    63         for(int j=20;j>=0;j--){
    64             if((ato[i][j]+bto[i][j]>xx&&j)||(!j&&ato[i][j]>xx))continue;
    65             sa+=ato[i][j];
    66             xx-=ato[i][j];
    67             if(bto[i][j]>xx){fl=1;break;}
    68             sb+=bto[i][j];xx-=bto[i][j];
    69             i=g[i][j];
    70         }
    71         if(!fl&&ato[i][0]<=xx)sa+=ato[i][0],i=co[i];
    72         i=i0;    
    73         if(sb==0)continue;
    74         if(mni==sa*1.0/sb&&h[id]<h[i])id=i;
    75         else if(mni>sa*1.0/sb)mni=sa*1.0/sb,id=i;
    76     }
    77     printf("%d
    ",id);m=read();
    78     for(int i=1;i<=m;i++){
    79         LL si=read(),xi=read();
    80         LL sa=0,sb=0;int fl=0;
    81         for(int j=20;j>=0;j--)
    82             if((j&&ato[si][j]+bto[si][j]<=xi)||(!j&&ato[si][0]<=xi)){
    83                 sa+=ato[si][j];xi-=ato[si][j];
    84                 if(bto[si][j]>xi){fl=1;break;}
    85                 xi-=bto[si][j];sb+=bto[si][j];
    86                 si=g[si][j];
    87             }
    88         if(!fl&&ato[si][0]<=xi)sa+=ato[si][0],si=co[si];
    89         printf("%lld %lld
    ",sa,sb);
    90     }
    91     return 0;
    92 }
    D1 T3

    Day2

    T1同余方程

    以前的博客->戳这里

    T2借教室

    题目链接

    二分第一个出现冲突的点,然后就差分前缀和判si[i]是否大于d[i]即可。复杂度O(nlog(n))。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 const int N=1e6+5;
     5 int read(){
     6     int ans=0,f=1;char c=getchar();
     7     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     8     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
     9     return ans*f;
    10 }
    11 int n,m;
    12 int di[N],dj[N],si[N],sj[N];
    13 int tr[N];
    14 bool check(int x){
    15     memset(tr,0,sizeof(tr));
    16     for(int i=1;i<=x;i++){
    17         tr[si[i]]+=dj[i];tr[sj[i]+1]-=dj[i];
    18     }
    19     int sum=0;
    20     for(int i=1;i<=n;i++){
    21         sum+=tr[i];
    22         if(sum>di[i])return 0;
    23     }
    24     return 1;
    25 }
    26 int main(){
    27     n=read();m=read();
    28     for(int i=1;i<=n;i++)di[i]=read();
    29     for(int i=1;i<=m;i++){
    30         dj[i]=read();si[i]=read();sj[i]=read();
    31     }
    32     int l=0,r=m+1;
    33     while(l<r-1){
    34         int mid=(l+r)>>1;
    35         if(check(mid))l=mid;
    36         else r=mid;
    37     }
    38     if(l==m)printf("0");
    39     else printf("-1
    %d",l+1);
    40     return 0;
    41 }
    D2 T2

    T3疫情控制

    题目链接

    挺难的一道题,然而我之前一个错的很离谱的贪心居然能过vijos上的全部数据......建议写完也去洛谷那边交一下......

    不合法无非就是军队数小于根节点的孩子数,没什么难度。

    二分一个时间,然后对于每支军队都尽量往上走。

    能走到根节点的军队入队,按照剩余可用时间从小到大排序;到不了的就停在最多能走到的点打个标记就行。

    dfs根的每棵子树,记一下当前子树是否还有叶子没被控制,有的话记录一下这棵子树里能走到根的最深点-->last(因为它最没用),然后根的次子节点入队。

    将子节点构成的队按距离从小到大排序。

    枚举每支军队,如果它原来属于子树还没被覆盖,就让它回到它原来的子树去,否则就把离根最近的子节点分配给它,当然到达不了就算了。

    判合法就很明显了吧......

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define mem(a,p) memset(a,p,sizeof(a))
      5 typedef long long LL;
      6 const int N=5e4+7;
      7 using std::sort;
      8 int n,m,first[N],tot=0,si[N],son[N],op;
      9 int gr[N][22],deep[N];
     10 LL dis[N][22],tofa[N];
     11 struct node{int ne,to;LL w;}e[N*2];
     12 struct no{LL w;int id;}q[N],st[N];
     13 bool cmp(no a,no b){return a.w<b.w;}
     14 int read(){
     15     int ans=0,f=1;char c=getchar();
     16     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     17     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}    
     18     return ans*f;
     19 }
     20 void ins(int u,int v,int w){
     21     e[++tot]=(node){first[u],v,w};first[u]=tot;
     22 }
     23 void dfs(int x,int fa){
     24     for(int i=1;(1<<i)<=deep[x];i++){
     25         gr[x][i]=gr[gr[x][i-1]][i-1];
     26         dis[x][i]=dis[x][i-1]+dis[gr[x][i-1]][i-1];
     27     }
     28     for(int i=first[x];i;i=e[i].ne){
     29         int to=e[i].to;
     30         if(to==fa)continue;
     31         gr[to][0]=x;dis[to][0]=e[i].w;
     32         deep[to]=deep[x]+1;
     33         tofa[to]=tofa[x]+e[i].w;
     34         son[x]++;
     35         dfs(to,x);
     36     }
     37 }
     38 bool ok[N],flag[N];
     39 int last;
     40 void work(int x,int fa,bool&le,bool p){
     41     for(int i=first[x];i;i=e[i].ne){
     42         int to=e[i].to;
     43         if(to==fa)continue;
     44         int pp=flag[to];
     45         work(to,x,le,pp|p);
     46     }
     47     if(!p&&son[x]==0)le=1;
     48     if(ok[x]&&tofa[last]<tofa[x])last=x;
     49 }
     50 int kk[N];
     51 bool vis[N];
     52 bool check(LL x){
     53     int sum=0;op=0;mem(ok,0);mem(flag,0);mem(kk,0);mem(vis,0);
     54     for(int i=1;i<=m;i++){
     55         LL x0=x;int id=si[i];
     56         if(tofa[si[i]]<=x){
     57             q[++sum]=(no){x-tofa[si[i]],si[i]};ok[si[i]]=1;
     58             continue;
     59         }
     60         for(int j=20;j>=0;j--){
     61             if((1<<j)>deep[id]||dis[id][j]>x0)continue;
     62             x0-=dis[id][j];id=gr[id][j];
     63         }
     64         flag[id]=1;
     65     }
     66     for(int i=first[1];i;i=e[i].ne){
     67         last=0;
     68         if(flag[e[i].to])continue;
     69         bool pp=!son[e[i].to];
     70         work(e[i].to,1,pp,0);
     71         if(!last&&ok[e[i].to])last=e[i].to;
     72         kk[last]=e[i].to;
     73         if(pp)st[++op]=(no){tofa[e[i].to],e[i].to};
     74         else vis[e[i].to]=1;
     75     }
     76     vis[0]=1;
     77     sort(q+1,q+1+sum,cmp);sort(st+1,st+1+op,cmp);int head=1;
     78     for(int i=1;i<=sum;i++){
     79         while(vis[st[head].id]&&head<=op)head++;
     80         if(!vis[kk[q[i].id]]&&tofa[kk[q[i].id]]>=st[head].w){
     81             vis[kk[q[i].id]]=1;
     82             continue;    
     83         }
     84         if(st[head].w>q[i].w)continue;
     85         head++;if(head>op)break;
     86     }
     87     while(vis[st[head].id]&&head<=op)head++;
     88     if(head<=op)return 0;
     89     return 1;
     90 }
     91 int main(){
     92     n=read();
     93     for(int i=1,a,b,c;i<n;i++){
     94         a=read();b=read();c=read();
     95         ins(a,b,c);ins(b,a,c);
     96     } 
     97     dfs(1,0);
     98     m=read();
     99     for(int i=1;i<=m;i++)si[i]=read();
    100     if(son[1]>m)return printf("-1"),0;
    101     LL l=0,r=1e13;
    102     while(l<r){
    103         LL mid=(l+r)>>1;
    104         if(check(mid))r=mid;
    105         else l=mid+1;
    106     }
    107     printf("%lld",l);
    108     return 0;
    109 }
    D2 T3
  • 相关阅读:
    使用Python的Mock库进行PySpark单元测试
    库龄报表的相关知识
    使用PlanViz进行ABAP CDS性能分析
    Spark SQL中列转行(UNPIVOT)的两种方法
    Spark中的一些概念
    使用Visual Studio Code进行ABAP开发
    2019年的几个目标
    Dom--样式操作
    Dom选择器--内容文本操作
    Javascript面向
  • 原文地址:https://www.cnblogs.com/JKAI/p/7789095.html
Copyright © 2020-2023  润新知