zoukankan      html  css  js  c++  java
  • 四川大学第二届SCUACM新生赛(同步赛)题解

    周末没事干,就不要脸地去一边吃饭一边看学弟沈阳拿银一边水了个比赛,水都水了,简单写个题解。

    比赛链接

    A,丁姐姐喜欢Fibonacci。签到1,斐波那契%3 1 1 0 1 1 0 1 1 0。。。,判断模3等于0就好了

     1 #include<cstdio>
     2 typedef long long ll;
     3 int main(){
     4     ll n;
     5     while(~scanf("%lld",&n)){
     6         if(n%3==0) printf(""odd"
    ");
     7         else printf(""even"
    ");
     8     }
     9     return 0; 
    10 } 
    A

    B.丁姐姐喜欢LCS。签到2.找最长的首尾相接的,那直接枚举答案的长度,然后进行暴力匹配。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 using namespace std;
     5 const int N=2e3+11;
     6 char a[N],b[N];
     7 int main(){
     8     while(~scanf("%s%s",a+1,b+1)){
     9         int lena=strlen(a+1),lenb=strlen(b+1),ans=0;
    10         for(int i=min(lena,lenb),j;i>=1;i--){
    11             for(j=1;j<=i;j++) if(b[j]!=a[lena-i+j]) break;
    12             if(j>i){
    13                 ans=i;
    14                 break;
    15             }
    16         }
    17         if(ans==0) printf(""NULL!"");
    18         else for(int i=1;i<=ans;i++) printf("%c",b[i]);
    19         printf("
    ");
    20     }
    21     return 0;
    22 } 
    B

    C.俏兔子大战傻贼鹰-Easy Version。简单模拟,判断一下有三张的牌的个数还有两张牌的个数即可,话说数据有点水,居然没有六张一样的牌

     1 #include<cstdio>
     2 #include<cstring> 
     3 char op,s[52];
     4 int num[10][5];
     5 int main(){
     6     int t,lens;
     7     while(~scanf("%d",&t)){
     8         getchar();
     9         scanf("%c",&op);
    10         while(t--){
    11             scanf("%s",s);
    12             lens=strlen(s);
    13             bool flag=true;
    14             for(int i=0;i<lens;i+=2){
    15                 int op1=s[i]-'0',op2;
    16                 if(s[i+1]=='S') op2=0;
    17                 else if(s[i+1]=='T') op2=1;
    18                 else op2=2;
    19                 num[op1][op2]++;
    20                 if(s[i+1]==op){
    21                     flag=false;
    22                     break;
    23                 }
    24             }
    25             int num1=0,num2=0;
    26             for(int i=1;i<=9;i++)
    27                 for(int j=0;j<3;j++){
    28                     if(num[i][j]==3) num1++;
    29                     else if(num[i][j]==2) num2++;
    30                     num[i][j]=0;
    31                 }
    32             if(flag&&((num1==4&&num2==1)||num2==7)) printf("Yes
    ");
    33             else printf("No
    ");
    34         }
    35     }
    36     return 0;
    37 }
    C

    D.俏兔子大战傻贼鹰-Hard Version。简单模拟2,改一下判断条件那里即可,优先三张连续的再考虑三张一样的。

     1 #include<cstdio>
     2 #include<cstring> 
     3 char op,s[52];
     4 int num[10][5];
     5 int main(){
     6     int t,lens;
     7     while(~scanf("%d",&t)){
     8         getchar();
     9         scanf("%c",&op);
    10         while(t--){
    11             scanf("%s",s);
    12             lens=strlen(s);
    13             bool flag=true;
    14             for(int i=0;i<lens;i+=2){
    15                 int op1=s[i]-'0',op2;
    16                 if(s[i+1]=='S') op2=0;
    17                 else if(s[i+1]=='T') op2=1;
    18                 else op2=2;
    19                 num[op1][op2]++;
    20                 if(s[i+1]==op){
    21                     flag=false;
    22                     break;
    23                 }
    24             }
    25             int num1=0,num2=0;
    26             for(int i=1;i<=9;i++)
    27                 for(int j=0;j<3;j++){
    28                     if(i<=7){
    29                         while(num[i][j]&&num[i+1][j]&&num[i+2][j]){
    30                             num[i][j]--;
    31                             num[i+1][j]--;
    32                             num[i+2][j]--;
    33                             num1++;
    34                         }
    35                     }
    36                     if(num[i][j]>=3) num1++;
    37                     if(num[i][j]==2) num2++;
    38                     num[i][j]=0;
    39                 }
    40             if(flag&&((num1==4&&num2==1)||num2==7)) printf("Yes
    ");
    41             else printf("No
    ");
    42         }
    43     }
    44     return 0;
    45 }
    D

    E.[模板]欧拉筛。简单数学题,用不到欧式筛,埃式筛即可,不过我平时都是用欧式筛。入手点,在模数p是1e5级别的数,大于模数的阶乘取模后都为0就不用考虑了,所以先预处理出1e5内素数,然后for到min(n,p)来计算答案就好。

     1 #include<cstdio>
     2 typedef long long ll;
     3 const int N=1e5+11;
     4 bool nop[N];
     5 int pn,pri[N];
     6 void init(){
     7     for(int i=2;i<N;i++){
     8         if(!nop[i]) pri[pn++]=i;
     9         for(int j=0;j<pn;j++){
    10             if(1ll*i*pri[j]>=N) break;
    11             nop[i*pri[j]]=true;
    12             if(i%pri[j]==0) break;
    13         }
    14     }
    15 }
    16 int main(){
    17     init();
    18     int t,n,p;
    19     scanf("%d",&t);
    20     while(t--){
    21         scanf("%d%d",&n,&p);
    22         ll jc=1,ans=0;
    23         for(int i=2;i<=p&&i<=n;i++){
    24             jc=jc*i%p;
    25             if(!nop[i]) ans=(ans+jc)%p;
    26         }
    27         printf("%d
    ",ans);
    28     } 
    29     return 0;
    30 }
    E

    F.[模板]后缀自动机。思维题。要是真的后缀自动机我还真不会。首先我们肯定可以想到是用S的最小后缀去跟T的最小前缀比较即可,S的最小后缀怎么求,后缀自动机?最小表示法?好像都不会,那么我们看T的最小前缀,那不就是第一个字符吗,所以只要判断S中有字典序小于T的第一个字符的字符即可。

     1 #include<cstdio>
     2 #include<cstring>
     3 const int N=2e5+11;
     4 char s1[N],s2[N];
     5 int main(){
     6     int t;
     7     scanf("%d",&t);
     8     while(t--){
     9         scanf("%s%s",s1,s2);
    10         int lens1=strlen(s1);
    11         bool flag=false;
    12         for(int i=lens1-1;i>=0;i--) if(s2[0]>s1[i]){
    13             flag=true;
    14             break;
    15         }
    16         if(flag) printf("YE5
    ");
    17         else printf("N0
    ");
    18     }
    19     return 0;
    20 }
    F

    G.走迷宫。数学题。可以看出就是螺旋矩阵给出序号求坐标,那么把它划分一层层,第一层的个数就有m+n-1+m-1+n-2也就是2*(n+m-2)个,第二层便是n-2,然后m-2,跟第一场的差便是8个,所以这是个等差数列,那么根据等差数列求和,我们就可以判断出给出的序号在哪一层,然后确定了在哪一层,再根据它在一条边判断即可,需要注意的是n=1,和m=1时的情况。

     1 #include<cstdio>
     2 #include<cmath> 
     3 #include<algorithm>
     4 using namespace std;
     5 typedef long long ll;
     6 void solve(ll n,ll m,ll k){
     7     if(k>=n*m) k=n*m;
     8     ll d=((n+m)*2-ceil(sqrt((n+m)*(n+m)*4-k*16)))/8; 
     9     d=min(min(n/2,m/2),d);
    10     ll x=1+d,y=1+d;
    11     k-=(d*(n+m)*4-d*d*8)/2;
    12     n-=d*2,m-=d*2;
    13     if(!k) y--;
    14     else if(n==1) y+=k-1;
    15     else if(m==1) x+=k-1;
    16     else{
    17         if(k<=m) y+=k-1;
    18         else if(k<=n+m-1) y+=m-1,x+=k-m;
    19         else if(k<=n+m*2-2) x+=n-1,y+=m*2+n-k-2;
    20         else x+=(n+m)*2-k-3;
    21     }
    22     printf("(%d,%d)
    ",x,y);
    23 }
    24 int main(){
    25     int t,q;
    26     ll n,m,k;
    27     scanf("%d",&t);
    28     while(t--){
    29         scanf("%lld%lld",&n,&m);
    30         scanf("%d",&q);
    31         while(q--){
    32             scanf("%lld",&k);
    33             solve(n,m,k+1); 
    34         }
    35     }
    36     return 0;
    37 }
    G

    H.捡金币。二维前缀和,个人感觉最难的一题吧。根据题意我们要求的就是一个菱形里的点权值和,但我只维护过正的矩形的和,没整过菱形的和,那咋办呢。通过点旋转公式,把整个图形旋转45度,它不就正的了吗,这时再维护这个正的二维前缀和即可。点旋转公式可以自行百度,然后旋转之后原先的坐标(x,y)便成了(√2/2(x+y),√2/2(x-y)),然后我们整体放大√2倍,就成了(x+y,x-y),x-y会存在负数,那便再加上y轴的偏移量,最后便是(x+y,x-y+m),因为k的点的绝对值坐标距离,所以不需要方法√2倍,否则要是两点之间的欧式距离的话,则也需要放大√2倍。

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 typedef long long ll;
     5 const int N=2e3+11;
     6 ll sum[N][N];
     7 int main(){
     8     int t,n,m,q,x,y,k;
     9     scanf("%d",&t);
    10     while(t--){
    11         scanf("%d%d",&n,&m);
    12         for(int i=0;i<=n+m;i++)
    13             for(int j=0;j<=n+m;j++) sum[i][j]=0;
    14         for(int i=1;i<=n;i++)
    15             for(int j=1;j<=m;j++){
    16                 x=i+j;y=i-j+m;
    17                 scanf("%lld",&sum[x][y]);
    18             }
    19         for(int i=1;i<=n+m;i++)
    20             for(int j=1;j<=n+m;j++)
    21                 sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
    22         scanf("%d",&q);
    23         int lx,ly,rx,ry;
    24         while(q--){
    25             scanf("%d%d%d",&x,&y,&k);
    26             lx=max(1,x+y-k),ly=max(1,x-y+m-k);
    27             rx=min(n+m,x+y+k),ry=min(n+m,x-y+m+k);
    28             printf("%lld
    ",sum[rx][ry]-sum[rx][ly-1]-sum[lx-1][ry]+sum[lx-1][ly-1]);
    29         }
    30     }
    31     return 0;
    32 }
    H

    I.排序。模拟,弄个结构体,照着题意来即可。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<tr1/unordered_map>
     4 #include<algorithm>
     5 using namespace std;
     6 const int N=55;
     7 struct Node{
     8     string name;
     9     int ts,zsj,tj[N],tg[N],sj[N];
    10     bool operator<(const Node &n1)const{
    11         return ts==n1.ts ? (zsj==n1.zsj ? name<n1.name : zsj<n1.zsj): ts>n1.ts;
    12     }
    13 }a[N];
    14 tr1::unordered_map<string,int> mmp;
    15 int main(){
    16     int t,n,m;
    17     string s;
    18     scanf("%d",&t);
    19     while(t--){
    20         scanf("%d%d",&n,&m);
    21         mmp.clear();
    22         for(int i=1;i<=m;i++){
    23             cin>>s;
    24             a[i].name=s;
    25             mmp[s]=i;
    26             for(int j=1;j<=n;j++){
    27                 a[i].ts=a[i].zsj=0;
    28                 a[i].tg[j]=a[i].tj[j]=a[i].sj[j]=0;
    29             }
    30         }
    31         int q,id,th,sj;
    32         scanf("%d",&q);
    33         while(q--){
    34             cin>>s;id=mmp[s];
    35             cin>>sj;cin>>s;th=s[0]-'A'+1;
    36             cin>>s;
    37             if(a[id].tg[th]) continue;
    38             if(s[0]=='A'){
    39                 a[id].tg[th]=1;a[id].ts++;
    40                 a[id].sj[th]=sj;
    41                 a[id].zsj+=sj+20*a[id].tj[th];
    42                 a[id].tj[th]++;
    43             }else if(s[0]!='C') a[id].tj[th]++;
    44         }
    45         sort(a+1,a+1+m);
    46         for(int i=1,ra=1;i<=m;i++){
    47             if(i>1&&(a[i].ts!=a[i-1].ts||a[i].zsj!=a[i-1].zsj)) ra=i;
    48             cout<<ra<<" "<<a[i].name<<" "<<a[i].ts<<" "<<a[i].zsj;
    49             for(int j=1;j<=n;j++){
    50                 printf(" ");
    51                 if(a[i].tg[j]){
    52                     printf("+%d(%d)",a[i].tj[j],a[i].sj[j]);
    53                 }else printf("-%d",a[i].tj[j]);
    54             }
    55             printf("
    ");
    56         }
    57         if(t) printf("
    ");
    58     }
    59     return 0;
    60 } 
    I

    J.n=a*b*c,数学题,由x*y<=n有x<=√n||y<=√n,那么√n枚举两个数,然后求第三个数,再更新一下答案即可。

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<algorithm>
     4 using namespace std;
     5 int main(){
     6     int t,n,m;
     7     scanf("%d",&t);
     8     while(t--){
     9         scanf("%d",&n);m=(int)sqrt(n);
    10         int a=0,b=-1,c=n+1,aa,bb,cc;
    11         for(int i=2;i<=m;i++)
    12             for(int j=2;j<=m;j++){
    13                 if(n%(i*j)!=0||i*j==n) continue;
    14                 aa=min(min(i,j),n/(i*j));
    15                 cc=max(max(i,j),n/(i*j));
    16                 bb=i+j+n/(i*j)-aa-cc;
    17                 if(cc-aa<c-a||(cc-aa==c-a&&aa<a)) a=aa,b=bb,c=cc;
    18             }
    19         if(a==0) printf("No solution
    ");
    20         else printf("%d=%d*%d*%d
    ",n,a,b,c); 
    21     } 
    22     return 0;
    23 }
    J

    K.梅森素数,3 7 31 127 8191,就这样吧。

    L.双流机场。思维题,一开始看错题意了,以为左上角能到其他地方即可,错了一发。然后仔细一看题意是任意两点可达,那就简单了。处于中间的点肯定会有能到达它并且从它出去的路线,所以我们只需要判读四个角不是没有进入的路线,或者没有出去的路线即可。

     1 #include<cstdio>
     2 const int N=1e5+11;
     3 char a[N],b[N];
     4 int main(){
     5     int t,n,m;
     6     scanf("%d",&t);
     7     while(t--){
     8         scanf("%d%d",&n,&m);
     9         scanf("%s%s",a+1,b+1);
    10         if(a[1]!=b[1]) printf("Sad
    ");
    11         else if(a[1]==b[m]) printf("Sad
    ");
    12         else if(a[n]==b[1]) printf("Sad
    ");
    13         else if(a[n]!=b[m]) printf("Sad
    ");
    14         else printf("Happy
    ");
    15     }
    16     return 0;
    17 }
    L

    M.lglg说要有题,于是便有了题。额,打表题,垃圾精度,怪恶心的,根据题目打表来观察即可,但精度很恶心恶心恶心。就小于3输出0,小于29输出1,小于11789输出2,其他输出3。

  • 相关阅读:
    性能测试常用业务模型分析
    性能常见模式
    C# 2第一个程序
    C# 1安装编译器
    eclipse安装maven错误总结
    Idea创建Maven项目
    Idea导入Eclipse项目
    软件需求与分析
    软件构造:完善口算题卡
    软件需求与分析
  • 原文地址:https://www.cnblogs.com/LMCC1108/p/11885035.html
Copyright © 2011-2022 走看看