zoukankan      html  css  js  c++  java
  • noi.ac 邀请赛1 By cellur925

    A. array

    考场:上来就想暴力,首先第一个子任务肯定没问题,怎么搞都行。然后第二个子任务用个数组记下新修的值就行了。第三个子任务用一下等差数列求和公式帮助求解,每次都重新算(因为每次改变全部元素)。期望得分80分,实际得分40分。原因有2:快速乘不仅没快,而且反而把我4个点搞TLE了....我再也不用手写大整数乘法了;5~8测试点,说好的只有A类型,结果考后改了一个多小时都过不了子任务,后来在辰哥的指导下发现数据有锅,5~8数据点藏着B类型的修改。我无fa♂可说。

      1 #include<cstdio>
      2 #include<algorithm>
      3 
      4 using namespace std;
      5 typedef long long ll;
      6 
      7 ll n,m;
      8 ll x,y;
      9 ll ans;
     10 char op[5];
     11 int seq[500];
     12 int a[50000090];
     13 bool vis[50000090];
     14 
     15 void re(ll &x)
     16 {
     17     x=0;
     18     char ch=getchar();
     19     bool flag=false;
     20     while(ch<'0'||ch>'9') flag|=(ch=='-'),ch=getchar();
     21     while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
     22     x=flag ? -x : x;
     23 }
     24 
     25 ll mul(ll a,ll b)
     26 {
     27     ll res=0;
     28     while(b)
     29     {
     30         if(b&1) res=(res+a);
     31         b>>=1;
     32         a=a*2;
     33     }
     34     return res;
     35 }
     36 
     37 void work1()
     38 {
     39     ll sta=n*(1+n)/2;
     40     ans=x*sta+y*n;
     41     printf("%lld
    ",ans);
     42     for(int i=2;i<=m;i++)
     43     {
     44         scanf("%s",op+1);
     45         re(x);re(y);
     46         ans=x*sta+y*n;
     47         printf("%lld
    ",ans);
     48     }
     49 }
     50 
     51 void work2()
     52 {
     53     ll sta=mul(n,1+n);
     54     sta>>=1;
     55     ans=sta;
     56     if(!vis[x])
     57     {
     58         vis[x]=1;
     59         ans-=x;
     60         ans+=y;
     61         a[x]=y;
     62     }
     63     printf("%lld
    ",ans);
     64     for(int i=2;i<=m;i++)
     65     {
     66         scanf("%s",op+1);
     67         re(x);re(y);
     68         if(!vis[x])
     69         {
     70             vis[x]=1;
     71             ans-=x;
     72             ans+=y;
     73             a[x]=y;
     74         }
     75         else
     76         {
     77             ans-=a[x];
     78             ans+=y;
     79             a[x]=y;
     80         }
     81         printf("%lld
    ",ans);
     82     } 
     83 }
     84 
     85 int main()
     86 {
     87     re(n);re(m);
     88     if(n<=100)
     89     {
     90         for(int i=1;i<=n;i++) seq[i]=i,ans+=i;
     91         for(int i=1;i<=m;i++)
     92         {
     93             scanf("%s",op+1);
     94             re(x);re(y);    
     95             if(op[1]=='A')
     96             {
     97                 ans=0;
     98                 for(int j=1;j<=n;j++)
     99                     seq[j]=j*x+y,ans+=seq[j];
    100                 printf("%lld
    ",ans);
    101             }
    102             else if(op[1]=='B')
    103             {
    104                 ans-=seq[x];
    105                 seq[x]=y;
    106                 ans+=y;
    107                 printf("%lld
    ",ans);
    108             }
    109         }
    110         return 0;
    111     }
    112     scanf("%s",op+1);
    113     re(x);re(y);
    114     if(op[1]=='A') work1();
    115     else if(op[1]=='B') work2();
    116     return 0;
    117 }
    期望的80

    正解:其实我想的很贴近了==。两个操作杂糅一起的情况时,A操作不会受到B操作的影响,而B操作可能会受到A操作的影响。于是我们需要记录一下之前的状态。如果在这个B操作与上一个B操作之间存在一个A操作,那么我们就不能无脑改值。记一个存新值的$seq$数组,再记一个时间戳记录状态的$mar$数组,我们就可以维护了。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<map>
     4 
     5 using namespace std;
     6 typedef long long ll;
     7 
     8 int pos=1;//注意初始值为1!!!!
     9 ll n,m;
    10 ll x,y,px=1,py;
    11 ll ans,sta;
    12 char op[5];
    13 int seq[50000090];
    14 int mar[50000090];
    15 
    16 int main()
    17 {
    18     scanf("%lld%lld",&n,&m);
    19     sta=(1+n)*n/2;ans=sta;
    20     for(int i=1;i<=m;i++)
    21     {
    22         scanf("%s",op+1);
    23         scanf("%lld%lld",&x,&y);    
    24         if(op[1]=='A')
    25         {
    26             pos++;
    27             px=x,py=y;
    28             ans=sta*x+y*n;
    29             printf("%lld
    ",ans);
    30         }
    31         else if(op[1]=='B')
    32         {
    33             if(mar[x]!=pos) ans=ans-(px*x+py)+y,mar[x]=pos;
    34             else ans=ans-seq[x]+y;
    35             seq[x]=y;
    36             printf("%lld
    ",ans);
    37         }
    38     }
    39     return 0;
    40 }
    AC

    B. computer

    考场:开始感觉题面晦涩难懂...手算了一下样例也对“随机选取”感到一头雾水...。于是跑去做了大模拟·T3。快结束的时候感觉不要挂题啊...于是逼着自己写了一个奇怪的暴力,因为是重复上述过程直到稳定,所以可以乱搞一个“随机算法”,让他跑2000次,目测能通过50%的数据,本来不抱希望的,结果我乱搞搞了最高的分数???

     1 #include<cstdio>
     2 #include<algorithm>
     3 
     4 using namespace std;
     5 
     6 int n,m;
     7 int val[2000];
     8 struct node{
     9     int id,f,t;
    10 }edge[100090];
    11 
    12 int main()
    13 {
    14     scanf("%d%d",&n,&m);
    15     for(int i=1;i<=m;i++)
    16         scanf("%d%d",&edge[i].f,&edge[i].t),edge[i].id=i;
    17     for(int i=2;i<=n;i++) val[i]=1e9;
    18     val[1]=0;
    19     for(int T=1;T<=2000;T++)
    20     {
    21         for(int i=1;i<=m;i++)
    22         {
    23             int x=edge[i].f;int y=edge[i].t;
    24             int t=max(i,val[x]);
    25             if(t<val[y]) val[y]=t;
    26             
    27             x=edge[i].t;y=edge[i].f;
    28             t=max(i,val[x]);
    29             if(t<val[y]) val[y]=t;
    30         }
    31     }
    32     for(int i=1;i<=n;i++) printf("%d
    ",val[i]);
    33     return 0;
    34 }
    50

    正解:裸的最短路嘤嘤嘤。我们再来看这台计算机的计算过程:

    • 1号CPU值为0,其他CPU值为1e9--各个点的CPU值为dis数组,即起点1到各个点的距离
    • 如果t比y号CPU上的值更小,就把y号CPU上的值改为t--这不就是松弛过程嘛。于是我们发现各边的边权即为边的编号。

    所以我们直接跑一遍dij就行了,但是要注意,这里更新就不是累加了,而是取最大值。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<queue>
     4 #include<cstring>
     5 #define maxn 100090
     6 #define maxm 300090
     7 
     8 using namespace std;
     9 
    10 int n,m,tot;
    11 int head[maxn],dis[maxn],vis[maxn];
    12 struct node{
    13     int to,next,val;
    14 }edge[maxm*2];
    15 
    16 void add(int x,int y,int z)
    17 {
    18     edge[++tot].to=y;
    19     edge[tot].next=head[x];
    20     head[x]=tot;
    21     edge[tot].val=z;
    22 }
    23 
    24 void dijkstra()
    25 {
    26     priority_queue<pair<int,int> >q;
    27     q.push(make_pair(0,1));
    28     for(int i=1;i<=n;i++) dis[i]=1e9;
    29     dis[1]=0;
    30     while(!q.empty())
    31     {
    32         int u=q.top().second;q.pop();
    33         if(vis[u]) continue;
    34         vis[u]=1;
    35         for(int i=head[u];i;i=edge[i].next)
    36         {
    37             int v=edge[i].to;
    38             int tmp=max(dis[u],edge[i].val);
    39             if(dis[v]>tmp)
    40             {
    41                 dis[v]=tmp;
    42                 q.push(make_pair(-dis[v],v));
    43             } 
    44         }
    45     } 
    46 }
    47 
    48 int main()
    49 {
    50     scanf("%d%d",&n,&m);
    51     for(int i=1;i<=m;i++)
    52     {
    53         int x=0,y=0;
    54         scanf("%d%d",&x,&y);
    55         add(x,y,i);add(y,x,i);
    56     }
    57     dijkstra();
    58     for(int i=1;i<=n;i++) printf("%d
    ",dis[i]);
    59     return 0;
    60 }
    AC

    小结:自己没看出来是最短路,还是太菜了...其实这个算法按这个描述还是很显然的啊(嘤)。还是要认真体会题目意思啊QAQ。


    C. eval

    题目描述

    或许这道题比经典的“表达式求值”还是要简单一点的。

    有一种简单的编程语言,我们如下定义其中的概念:

    • 常数:单个数字,即 0 到 9。注意不会出现多位数字的情况。
    • 变量:单个大写字母,即 A 到 Z。每个变量可以存储一个整数,所有变量的初始值为 0
    • 值:常数或者变量。
    • 赋值语句:由变量、=、值构成,例如 A=3B=AC=C。表示将变量修改为右侧的值。
    • 加法语句:由变量、+=、值构成,例如 A+=9B+=B。表示将变量额外加上右侧的值。
    • 语句:赋值语句、加法语句或者循环语句。
    • 循环语句:由 for(、变量、,、值、,、值、)、语句构成,例如 for(I,0,9)A+=Ifor(I,0,9)for(J,0,I)A+=J。设两个值在此时依次为 a 和 b,则:
      • 所有的输入数据保证此时 ab
      • 依次令变量取 a,a+1,a+2,,b,计算右侧的语句。
      • 整个循环语句结束后,变量的值取 b。
      • 右侧的语句中,保证不会对循环变量进行修改(即不会出现在赋值语句和加法语句的左侧,也不会成为另一个循环语句的变量),并且如果 a 和 b 是变量,也不会对其进行修改。

    考场:模拟啊...辰哥最强。感觉还是比较可做的,最后就是循环嵌套不会处理了,于是期望得分60分。结果考后发现循环语句中的初值与末值也有可能是变量,于是跑了20分...难受。稽不如人肝败下风而且最后的时候还好检查了,少讨论了一种变量为字母/数字的情况。而且还检查出来挂文件了qwq。

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<map>
      4 #include<cstring>
      5 #include<cctype>
      6 
      7 using namespace std;
      8 
      9 int len,num[200],vis[1000];
     10 char fac[200];
     11 map<char,int>od;
     12 
     13 int ksm(int a,int b)
     14 {
     15     int tmp=1;
     16     while(b)
     17     {
     18         if(b&1) tmp=tmp*a;
     19         b>>=1;
     20         a=a*a;
     21     }
     22     return tmp;
     23 }
     24 
     25 int chang(int pos)
     26 {
     27     int tmp=0,lc=0;
     28     for(int i=pos;i<=len;i++) num[i]=fac[i]-'0';
     29     for(int i=len;i>=pos;i--)
     30         tmp+=ksm(10,lc)*num[i],lc++;
     31     return tmp;
     32 }
     33 
     34 void output()
     35 {
     36     if(od['A']!=0) printf("A=%d
    ",od['A']);
     37     if(od['B']!=0) printf("B=%d
    ",od['B']);
     38     if(od['C']!=0) printf("C=%d
    ",od['C']);
     39     if(od['D']!=0) printf("D=%d
    ",od['D']);
     40     if(od['E']!=0) printf("E=%d
    ",od['E']);
     41     if(od['F']!=0) printf("F=%d
    ",od['F']);
     42     if(od['G']!=0) printf("G=%d
    ",od['G']);
     43     if(od['H']!=0) printf("H=%d
    ",od['H']);
     44     if(od['I']!=0) printf("I=%d
    ",od['I']);
     45     if(od['J']!=0) printf("J=%d
    ",od['J']);
     46     if(od['K']!=0) printf("K=%d
    ",od['K']);
     47     if(od['L']!=0) printf("L=%d
    ",od['L']);
     48     if(od['M']!=0) printf("M=%d
    ",od['M']);
     49     if(od['N']!=0) printf("N=%d
    ",od['N']);
     50     if(od['O']!=0) printf("O=%d
    ",od['O']);
     51     if(od['P']!=0) printf("P=%d
    ",od['P']);
     52     if(od['Q']!=0) printf("Q=%d
    ",od['Q']);
     53     if(od['R']!=0) printf("R=%d
    ",od['R']);
     54     if(od['S']!=0) printf("S=%d
    ",od['S']);
     55     if(od['T']!=0) printf("T=%d
    ",od['T']);
     56     if(od['U']!=0) printf("U=%d
    ",od['U']);
     57     if(od['V']!=0) printf("V=%d
    ",od['V']);
     58     if(od['W']!=0) printf("W=%d
    ",od['W']);
     59     if(od['X']!=0) printf("X=%d
    ",od['X']);
     60     if(od['Y']!=0) printf("Y=%d
    ",od['Y']);
     61     if(od['Z']!=0) printf("Z=%d
    ",od['Z']);
     62 }
     63 
     64 int main()
     65 {
     66     while(scanf("%s",fac+1)!=EOF)
     67     {
     68         len=strlen(fac+1);
     69         if(fac[1]!='f')// no cycle structures
     70         {
     71             if(fac[2]=='+') // add structures
     72             {
     73                 char qwq=fac[1],qaq=fac[4];
     74                 if(isdigit(fac[4])) od[qwq]+=chang(4);// add digit
     75                 else od[qwq]+=od[qaq];// add alpha
     76             }
     77             else // assignment structures
     78             {
     79                 char qwq=fac[1];
     80                 if(isdigit(fac[3])) od[qwq]=chang(3);
     81                 else od[qwq]=od[fac[3]];
     82             }
     83             continue;
     84         }
     85         char qwq=fac[5];
     86         char qaq=fac[11];
     87         if(fac[12]=='+') // add with cycle
     88         {
     89             int cnt=(fac[9]-'0')-(fac[7]-'0')+1;
     90             if(fac[len]==qwq) // add the same with cycle
     91             {
     92                 int to=fac[9]-'0';
     93                 int be=fac[7]-'0';
     94                 od[qaq]+=(be+to)*cnt/2;
     95             }
     96             else 
     97             {
     98 /*digit*/        if(isdigit(fac[len])) od[qaq]+=cnt*(fac[len]-'0');
     99 /*different*/    else od[qaq]+=cnt*od[fac[len]];
    100             }
    101         }
    102         else// assignment with cycle
    103         {
    104             if(fac[len]==qwq)
    105                 od[qaq]=fac[9]-'0';
    106             else
    107             {
    108                 if(isdigit(fac[len])) od[qaq]=fac[len]-'0';
    109                 else od[qaq]=od[fac[len]];
    110             }
    111         }
    112         od[qwq]=fac[9]-'0';// announce change
    113     }
    114     output();
    115     return 0;
    116 }
    40
     1 #include<cstdio>
     2 #include<cctype>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<iostream>
     6 
     7 using namespace std;
     8 typedef long long ll;
     9 ll sjt=1000000000000;
    10 ll cmp=2000000000000;
    11 
    12 char tmp[20];
    13 ll tong[1000];
    14 char fac[200];
    15 
    16 void spj(int pos)
    17 {
    18     cout<<(char)(pos+'A')<<"="<<"...";
    19     ll st=tong[pos];
    20     for(int i=9;i>=1;i--)
    21         tmp[i]=st%10+'0',st/=10;
    22     for(int i=1;i<=9;i++) cout<<tmp[i];
    23     printf("
    ");
    24 }
    25 
    26 void output()
    27 {
    28     for(int i=0;i<=25;i++)
    29         if(tong[i])
    30         {
    31             if(tong[i]>=1000000000) spj(i);
    32             else cout<<(char)(i+'A')<<"="<<tong[i]<<endl;
    33         }
    34 }
    35 
    36 void cycle(ll pos);
    37 
    38 void work(ll pos)
    39 {
    40     if(fac[pos]=='f') cycle(pos);
    41     else
    42     {
    43         ll ch=fac[pos]-'A';
    44         if(fac[pos+1]=='+')
    45         {
    46             if(isdigit(fac[pos+3])) tong[ch]+=fac[pos+3]-'0';
    47             else tong[ch]+=tong[fac[pos+3]-'A'];
    48             while(tong[ch]>cmp) tong[ch]-=sjt;
    49         }
    50         else
    51         {
    52             if(isdigit(fac[pos+2])) tong[ch]=fac[pos+2]-'0';
    53             else tong[ch]=tong[fac[pos+2]-'A'];
    54         }
    55     }
    56 }
    57 
    58 void cycle(ll pos)
    59 {
    60     ll ch=fac[pos+4]-'A';
    61     ll posl=pos+6,posr=pos+8,l=0,r=0;
    62     if(isdigit(fac[posl])) l=fac[posl]-'0';
    63     else l=tong[fac[posl]-'A'];
    64     if(isdigit(fac[posr])) r=fac[posr]-'0';
    65     else r=tong[fac[posr]-'A'];
    66     for(ll i=l;i<=r;i++)
    67         tong[ch]=i,work(pos+10);
    68     while(tong[ch]>cmp) tong[ch]-=sjt;
    69 }
    70 
    71 int main()
    72 {
    73     while(scanf("%s",fac+1)!=EOF)
    74         work(1);
    75     output();
    76     return 0;
    77 }
    AC

    小结:还是模拟考虑的细节不够&码力太弱了嘤嘤嘤。

    正解在博客园上显示不出来,我也很难受啊,贴链接

    今天感觉海星..比前两天正睿考试的状态好些了...还会继续恢复的(本来就弱啊),今天题还是比较简单的,我分还是低啊(菜)。T3锅了20分就很难受了,还是细节真·重要啊qwq.而且最近好像一直没有在考场上A题了,是在专业打暴力233。其实有的时候思路和正解已经很贴近了,就差最后一步了,还是要多思考a(光速逃

  • 相关阅读:
    TP5框架 《防sql注入、防xss攻击》
    jsonp跨域的原理
    PHP程序发送HTTP请求代码
    encodeURI()和encodeURIComponent() 区别
    密码存储中MD5的安全问题与替代方案
    获取用户Ip地址通用方法常见安全隐患(HTTP_X_FORWARDED_FOR)
    PHP中的调试工具 --Xdebug安装与使用
    手机端页面自适应解决方案—rem布局(进阶版,附源码示例)
    thinkphp 微信授权登录 以及微信实现分享
    PHP中使用CURL之php curl详细解析和常见大坑
  • 原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9823103.html
Copyright © 2011-2022 走看看