HPU2017-2016级暑期集训练习赛 【题解】

赛后分析,前半段心不静,心态有点乱,导致简单题一直wa。后半段才逐渐调整回来。 再一次感觉到心态很重要【ps 没事别看rank】

A 题 利息计算
分析, 题目信息好乱,但是看过的人很多,就想了肯定很简单,就按照最简单的写了。(其实题目把公式都说了,带公式就可以了)
代码

#include<cstdio>
#include<algorithm>
#include<math.h>
#include<queue>
#include<map>
#define LL long long 
using namespace std;
const  int MAXN =1000000+100;
const  int MAXM= 1e6;

int main(){
   int t;scanf("%d",&t);
   int y,q;
   double e,f,g;
   while(t--){
    scanf("%d%d%lf%lf%lf",&y,&q,&e,&f,&g);
    double m1=y*(1+e/100*q/365);
    m1=m1*(1+g/100);
    double m2=y*(1+f/100*(q+365)/365);
    printf("%.1lf\n%.1lf\n",m1,m2);
   }
    return 0;
}

B Picture
分析,没什么好说的,就是模拟,。
代码

#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<queue>
#define LL long long 
using namespace std;
const  int MAXN =1e5;
const  int MAXM= 1e6;
int main(){

    int n,m;
    while(~scanf("%d%d",&n,&m)){//注意这里是n为列,m为行
        for(int j=1;j<=m+2;j++){
            for(int i=1;i<=n+2;i++){
                if(i==1&&j==1) putchar('+');
                else if(i==n+2&&j==1) putchar('+');
                else if(i==1&&j==m+2) putchar('+');
                else if(i==n+2&&j==m+2) putchar('+');
                else if(j==1||j==m+2) putchar('-');
                else if(i==1||i==n+2) putchar('|');
                else putchar(' ');
            }
            putchar('\n');
        }
        putchar('\n');
    }
    return 0;
}

C - ZOJ
分析,同样是模拟,要分清楚各种情况,分别讨论就行。【细心就可以,我就是不细心wa一次】
代码

#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<queue>
#define LL long long 
using namespace std;
const  int MAXN =1e5;
const  int MAXM= 1e6;
char s[MAXN];
int main(){

    while(scanf("%s",s)&&s[0]!='E'){
        int z=0;int o=0;int j=0;
        for(int i=0;s[i];i++){
            if(s[i]=='Z') z++;
            if(s[i]=='O') o++;
            if(s[i]=='J') j++;
        }

        int cnt=min(min(z,o),j);
        z-=cnt;o-=cnt;j-=cnt;
        while(cnt--) printf("ZOJ");

        if(z==0){
            int k=min(o,j);
            o-=k;j-=k;
            while(k--) printf("OJ");
            while(o--) printf("O");
            while(j--) printf("J");
         }else if(o==0){
            int k=min(z,j);
            z-=k;j-=k;
             while(k--) printf("ZJ");
             while(z--) printf("Z");
             while(j--) printf("J");
         }else if(j==0){
            int k=min(z,o);
            z-=k;o-=k;
            while(k--) printf("ZO");
            while(z--) printf("Z");
            while(o--) printf("O");
         }
         putchar('\n');
    }
    return 0;
}

D - 18岁生日
分析, 就是弄清楚闰年2月是29,这一个就可以了,然后就分开一步步算就可以了。

#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<queue>
#define LL long long 
using namespace std;
const  int MAXN =1e5;
const  int MAXM= 1e6;
int mon[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};

bool pan(int i){
    return i%4==0&&i%100!=0||i%400==0;
}
int main(){
    int t;scanf("%d",&t);
    while(t--){
        int y,m,d;
        scanf("%d-%d-%d",&y,&m,&d);
        if(m==2&&d==29) {if(!pan(y+18)) puts("-1");}//出生在2月29的人只能18岁的时候还是闰年才可以。
          else{
            int cnt=0;  // 之后分三部分

            if(pan(y)) mon[2]=29;else mon[2]=28; //出生当年
            cnt+=mon[m]-d;
            for(int i=m+1;i<13;i++)
            cnt+=mon[i];    

            for(int i=y+1;i<y+18;i++) //出生后一年到17岁那年
            if(pan(i)) cnt+=366;else cnt+=365;

           if(pan(y+18)) mon[2]=29;else mon[2]=28;// 18岁那年
           for(int i=1;i<m;i++)
           cnt+=mon[i]; 

            printf("%d\n",cnt+d);
        }
    }
    return 0;
}

E - 统计元音
水题,(心态最乱的时候,这道题居然wa了三次,吐血)
代码

#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<queue>
#define LL long long 
using namespace std;
const  int MAXN =1e5;
const  int MAXM= 1e6;
char s[MAXN];
int main(){
    int t ;
    scanf("%d",&t);
    getchar();//吸收回车
    for(int k=1;k<=t;k++){
        int a,e,i,o,u;
        a=e=i=o=u=0;
        gets(s);
        for(int j=0;s[j];j++){
            if(s[j]=='a') a++;
            if(s[j]=='e') e++;
            if(s[j]=='i') i++;
            if(s[j]=='o') o++;
            if(s[j]=='u') u++;
         }
         printf("a:%d\n",a);
         printf("e:%d\n",e);
         printf("i:%d\n",i);
         printf("o:%d\n",o);
         printf("u:%d\n",u);
        if(k!=t) printf("\n");
     }
    return 0;
}

F - N!Again
同余定理的简单应用和找规律。我记得原题的N范围非常非常大 。
代码

#include<cstdio>
#include<algorithm>
#include<math.h>
#include<queue>
#define LL long long 
using namespace std;
const  int MAXN =1e5;
const  int MAXM= 1e6;
const int mod =2009;
int main(){
     LL n;
      while(~scanf("%lld",&n)){
        LL ans=1;
        if(n<=50) //当n为41 的时候就已经全是0了,因为之前有
    //个数z整除了2009 ,所以之后的数字都是这个z的倍数,故之后的数字都可以整除。
        for(LL i=1;i<=n;i++)
            ans=(ans%mod*i%mod)%mod;
        else ans=0;

        printf("%lld\n",ans);
       }
    return 0;
}

G - 进制转换
数学题,
代码

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<cstring>
#include<iostream>
#define LL long long 
using namespace std;
const  int MAXN =1e5;
const  int MAXM= 1e6;
int main(){
    int n;int r;
    while(scanf("%d%d",&n,&r)!=EOF){
        int f=1; if(n<0) f=-1;  n=abs(n);
        string s="";
        while(n){
            int k=n%r;
            if(k<10) s+=k+'0';
            else s+=k+'A'-10;
            n/=r;
         }
        if(f==-1)putchar('-') ;
        reverse(s.begin(),s.end());
         cout<<s<<endl;
     }
    return 0;
}

H - 整数解
暴力解,m*n才+-10000。说明m n不大 ,可以枚举
代码

#include<cstdio>
#include<algorithm>
#include<math.h>
#include<queue>
#define LL long long 
using namespace std;
const  int MAXN =1e5;
const  int MAXM= 1e6;

int main(){
    int n,m;
    while(scanf("%d%d",&n,&m)&&(n||m)){
        int i,j;
        for(i=-10000;i<=10000;i++)
            if((n-i)*i==m) break;
        if(i==10000+1) puts("No");
        else puts("Yes");
     }
    return 0;
}

I - 所爱图书
随便一个STL(map,set)都可以用。
代码

#include<cstdio>
#include<algorithm>
#include<math.h>
#include<queue>
#include<map>
#define LL long long 
using namespace std;
const  int MAXN =1e5;
const  int MAXM= 1e6;
map<int,int>mp; // 我用的map,来标记一个数 是不是出现过,其实用一个数组也可以。
int arr[MAXN];
bool cmp(int a,int b){
    return a>b;
}
int main(){
    int n;scanf("%d",&n);
    int ge=0;
    for(int i=0;i<n;i++){
        int a;scanf("%d",&a);
        if(!mp[a]) {
            arr[ge++]=a;
            mp[a]=1;
           }
       }
    sort(arr,arr+ge,cmp);
    int have=0;// 控制空格 
    for(int i=0;i<ge;i++){
        if(have++) putchar(' ');
        printf("%d",arr[i]);
    }
    return 0;
}

J - 美素数
感觉都 这道题都写烂了【ps一定要深刻理解这里用的打表,有很有用的技巧】
代码

#include<cstdio>
#include<algorithm>
#include<math.h>
#include<queue>
#include<map>
#define LL long long 
using namespace std;
const  int MAXN =1000000+100;
const  int MAXM= 1e6;
bool su[MAXN]={1,1,0};
void dabiao(){  //素筛
    for(int i=2;i*i<MAXN;i++)
    if(!su[i])
    for(int j=i*i;j<MAXN;j+=i)
    su[j]=1;
}
int getn(int x){ //得到各个位之和
    int cnt=0;
    while(x){
        cnt+=x%10;
        x/=10;
    }
    return cnt;
}
int arr[MAXN]={0,0,1,2};//重点
int main(){
    dabiao();
    for(int i=4;i<MAXN;i++){
        if(!su[i]&&!su[getn(i)]) arr[i]=arr[i-1]+1;
        else arr[i]=arr[i-1];
      }
    int t;scanf("%d",&t);
    int k=1;
    while(t--){
        int l,r;
        scanf("%d%d",&l,&r);
        printf("Case #%d: %d\n",k++,arr[r]-arr[l-1]);
    }
    return 0;
}

K - Ohana Cleans Up
分析 靠感觉吧,就是找到相同的字符串 次数最多的就可以。
这里用map 很简单。

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<cstring>
#include<iostream>
#include<map>
#define LL long long 
using namespace std;
const  int MAXN =1e5;
const  int MAXM= 1e6;
map<string,int>mp;
int main(){
    int n;
    scanf("%d",&n);
    string s="";
    getchar();
    int cnt=-1;
    for(int i=1;i<=n;i++){
        cin>>s; mp[s]++;
        cnt=max(mp[s],cnt);
      }
    printf("%d\n",cnt);
    return 0;
}

L - Alice, Bob, Two Teams
分析,暴力过

#include<cstdio>
#include<algorithm>
#include<math.h>
#include<queue>
#include<map>
#define LL long long 
using namespace std;
const  int MAXN =5*1e5+10;
const  int MAXM= 1e6;
int arr[MAXN];
char s[MAXN];
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();} 
    return x*f; // 刚开始没想那么多,怕暴力时间不够,就特意加的输入挂
}
/*-------------------------------------*/
int main(){
    int n;scanf("%d",&n);
    for(int i=1;i<=n;i++) 
    arr[i]=read();
    scanf("%s",s+1);
    LL bcnt=0;//存放 初始状态时候的b的strength得个数
    for(int i=1;i<=n;i++){
        if(s[i]=='B') {
            bcnt+=(LL)arr[i];
            arr[i]=-arr[i];// 之后要翻转,如果翻到B,
  //那么一定会将B化为A,肯定要减掉这个值。而A不用管,翻转过来一定会加的。
          }
    }
    LL maxbcnt=bcnt;  LL t=bcnt;
    for(int i=1;i<=n;i++){  //正向暴力一遍
        bcnt=bcnt+(LL)arr[i];
        maxbcnt=max(bcnt,maxbcnt);
    }

    for(int i=n;i>=1;i--){//反向暴力一遍  取最大值就可以
        t=t+(LL)arr[i];
        maxbcnt=max(t,maxbcnt);
    }
    printf("%lld\n",maxbcnt);
    return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值