五一-----五五训练总结

142 篇文章 0 订阅

1.[Gym-102770A]

题意:输出两个日期作为左右端点,从左边的天数开始,一直到右边的天数结束,问从该区间里符合条件的天数(条件为日期中含有“202”这个子串的),要注意闰年。

这题我们认为就是一个体力活。。。先把第一天和最后一天拿出来单独讨论,然后把中间的用一个for循环做出来。但这样做竟然超时了,那时候我想竟然这种体力活的题还能超时,再改成scanf

后还是超时,我们就蔫儿了。之后看了个题解,感觉思路非常的棒,现在把思路复述一下。

思路:首先打表,他用了三重循环都没超时(之后想了下感觉没毛病,他是在T循环外打表的,所以打一次就够了,而之前我们的代码要运行t次,所以会超时),他那个判断是不是符合条件的方法

也很好,将日期转变为一个八位数x,然后对1000取余看看是否是202,如果是就return true,如果不是x就除以10再进行知道x==0为止,如果都不行就return false。

#include <iostream>

using namespace std;
int yf(int a,int b){
    if(b==2){
    if(a%400==0||(a%4==0&&a%100!=0)){
      return 29;
   }
   else return 28;}
    if((b<8&&b%2!=0)||(b>=8&&b%2==0)){
        return 31;
    }
   else  return 30;
   }

bool pd(int a){
while(a!=0){
    if(a%1000==202){
    return true;
}
a/=10;
}
return false;
}
long long  a[10001][13][32];
int main()
{
  int t;      long long  ans=0;
   for(int i=2000;i<=9999;i++){
        for(int j=1;j<=12;j++){
            for(int k=1;k<=yf(i,j);k++){
                if(pd(i*10000+j*100+k)){
                    ans++;
                }
                a[i][j][k]=ans;
            }
        }
      }
  for(cin>>t;t;t--)
  {
      int y1,y2,m1,m2,d1,d2;
      cin>>y1>>m1>>d1>>y2>>m2>>d2;


      if(pd(y1*10000+m1*100+d1)){
        cout<<a[y2][m2][d2]-a[y1][m1][d1]+1<<endl;
      }
      else cout<<a[y2][m2][d2]-a[y1][m1][d1]<<endl;
  }
    return 0;
}

2.Gym - 102803G

题意:给出一个数n,小c先说出一个n的真因数m,然后小d再说出一个m的真因数出来,无法说出来的人获胜,真因数是除了1和本身之外的因数,小c要在保证赢的情况下说的数尽可能地大,如果小c直接

赢得话输出0,无论怎样都输的话输出-1,这两种都不满足就输出他说出的最大的数。

思路:输出0或-1的情况都好判断,最大数的情况就是从后往前找n的最大因数i,然后n=i,然后输出倒数第二个符合条件的数i就可以了,这样可保证小c必赢且是最大的。

#include <iostream>

using namespace std;
int main()
{
 int t;
 cin>>t;
 while(t--){
    int n;
    cin>>n;
    int sum=0;
    int ans[100010];

   for(int i=n/2+1;i>=2;i--){
        if(n%i==0){

            sum++;
            ans[sum]=i;
            n=i;//替换n

        }
    }
    if(sum==0){
        cout<<0<<endl;
    }
    if(sum==1){
        cout<<"-1"<<endl;
    }
    if(sum>=2){
        cout<<ans[sum-1]<<endl;//输出倒数第二个
    }
 }
    return 0;
}

3.Gym - 102803A

题意:给你四个函数,让你求这个函数所围成的面积,这个图形大致就是这样的:

大概是刚学了点积分,我竟然傻乎乎的想用积分去做,但碰到反三角函数之后我就觉得我已经无了,还好队友及时想出来了。

思路:上面两个圆的面积好说,下面那两块其实可以互补成为一个长方形,然后只要算一个圆和一个矩形的面积就OK了,通过那四个函数不难推出圆的半径为a,矩形长为2b,宽为2a。

#include <bits/stdc++.h>

using namespace std;
int main()
{
 int t;
 cin>>t;
 while(t--){
 double a,b;
    cin>>a>>b;
    double c=a*a*3.14159265358 + 2*a*2*b;
    cout<<fixed<<setprecision(8)<<c<<endl;

 }
    return 0;
}

4.Gym - 102219A

题意:输出按条件旋转后的图形。

思路:一共就是有四种情况,1.旋转之后和原来一样的;2.向右转了一次或向左转了三次;3.向右转了两次或向左转了两次;4.向右转了三次或向左转了一次。列举出这四种情况之后再判断是哪种情况即可,

队友写的旋转的方法感觉还是挺好的,借鉴一下。

#include <bits/stdc++.h>

using namespace std;
int main(){
   int n;
   string s;
   cin>>n;
   cin>>s;
   int l=0,r=0;
   char char1[1010][1010];
   for(int i=0;i<s.size();i++){
    if(s[i]=='L'){
        l++;
    }
    else r++;
   }
    int lr=(r-l)%4;
   for(int i=1;i<=n;i++){
    for(int j=1;j<=n;j++){
        cin>>char1[i][j];
    }
   }
   if(lr==0){
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            cout<<char1[i][j];
        }
        cout<<endl;
    }
   }
  else if(lr==1||lr==-3){
    for(int i=1;i<=n;i++)
        {
            for(int j=n;j>=1;j--)
            {
                 if(char1[j][i]=='>')
                 {
                     char1[j][i]='v';

                 }
                 else if(char1[j][i]=='v')
                 {
                     char1[j][i]='<';

                 }
                 else if(char1[j][i]=='<')
                 {
                     char1[j][i]='^';

                 }
                 else if(char1[j][i]=='^')
                 {
                     char1[j][i]='>';

                 }

                cout<<char1[j][i];
            }
            cout<<endl;
        }
    }
     else if(lr==2||lr==-2)
    {
        for(int i=n;i>0;i--)
        {
            for(int j=n;j>0;j--)
            {
                if(char1[i][j]=='>')
                 {
                     char1[i][j]='<';
                 }
                 else if(char1[i][j]=='v')
                 {
                     char1[i][j]='^';
                 }
                 else if(char1[i][j]=='<')
                 {
                     char1[i][j]='>';
                 }
                 else if(char1[i][j]=='^')
                 {
                     char1[i][j]='v';
                 }
                cout<<char1[i][j];
            }
            cout<<endl;
        }
    }
    else if(lr==3||lr==-1){
        for(int i=n;i>=1;i--)
        {
            for(int j=1;j<=n;j++)
            {
                 if(char1[j][i]=='>')
                 {
                     char1[j][i]='^';

                 }
                 else if(char1[j][i]=='v')
                 {
                     char1[j][i]='>';

                 }
                 else if(char1[j][i]=='<')
                 {
                     char1[j][i]='v';

                 }
                 else if(char1[j][i]=='^')
                 {
                     char1[j][i]='<';

                 }

                cout<<char1[j][i];
            }
            cout<<endl;
        }
    }
    return 0;
}

5.Gym - 102220C

题意:输入n条直线,问有几对相交的直线。

思路:将直线化成Ax+By+c=0的形式方便操作,重合的话需要A,B,c都相等,而平行的话只需要A,B相等,所以所有的对数再加上重合的对数再减去平行的对数即为我们要求的相交的对数。

#include <bits/stdc++.h>

using namespace std;
struct zb{
long long a,b,c;
friend bool operator <(zb a,zb b){
 if(a.a!=b.a) return a.a<b.a;
 else if(a.b!=b.b) return a.b<b.b;
 return a.c<b.c;
}
 
}a[100010],b;
map<zb,long long>mp1,mp2;
long long t,n;
int main(){
    ios::sync_with_stdio(0);
    cin>>t;
    while(t--){
        long long xa,ya,xb,yb;
        mp1.clear();
        mp2.clear();
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>xa>>ya>>xb>>yb;
            yb=ya-yb;
            xb=xa-xb;
            long long k=__gcd(yb,xb);
            yb/=k;xb/=k;
            a[i].a=xb;
            a[i].b=-yb;
            a[i].c=yb*xa-xb*ya;//
            if(a[i].a<0){
                a[i].a=-a[i].a;
                a[i].b=-a[i].b;
                a[i].c=-a[i].c;
            }                  //上面的操作是将直线化为Ax+By+c=0的形式
            b.a=a[i].a;b.b=a[i].b;b.c=0;
            mp1[a[i]]++;
            mp2[b]++;
              //用map容器存起来,之后进行比较
        }
       
        long long ans=n*(n-1)/2;
        for(auto i=mp1.begin();i!=mp1.end();i++){
            long long te=i->second;
            ans+=te*(te-1)/2;
        }
        for(auto i=mp2.begin();i!=mp2.end();i++){
            long long te=i->second;
            ans-=te*(te-1)/2;
        }
 //auto可以自动识别变量类型,但变量要进行初始化
 
     
        cout<<ans<<endl;
    }
    return 0;
}

6.Gym - 102220B

题意:一共有n颗糖果,m钟,每个糖果有两个值a为价值,b为种类,所有种类之中选的糖果数量的最大值为c,第l种糖果至少选l[i]个,问选的糖果的总价值和除以c的最大值。

思路:先处理一下选了多少个糖果的价值和是多少,然后枚举分母,选择分子最大的。

这道题看来看去还是有不明白的地方,先写上,等更厉害一些后再回来看。。。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,m;
ll t;
vector<ll>v[100005]; //每种中的价值有哪些
ll l[100005];
ll s,c;
ll ms[100005];
bool cmp(ll a,ll b)
{
    return a>b;
}
int main()
{
    ios::sync_with_stdio(0);
    cin>>t;
    while(t--)
    {
        cin>>n>>m;
        for(int i =1;i<=m;i++)
        {
            cin>>l[i];
            v[i].clear();
        }
        memset(ms,0,sizeof(ll)*(n+2));
        ll x,y;
        for(int i =1;i<=n;i++)
        {
            cin>>x>>y;
            v[y].push_back(x);
        }
        ll maxx=-1;
        for(int i =1;i<=m;i++)
        {
            maxx=max((ll)v[i].size(),maxx);
            sort(v[i].begin(),v[i].end(),cmp);
            ll tmp=0;
            for(int j = 0;j<v[i].size();j++)
            {
                tmp+=v[i][j];
                if(j+1>=l[i])   //小于l[i]时不算在价值和里
                 {
                     ms[j+1]+=tmp;
                     tmp=0;
                 }
            }
        }
        ll as=-1,ac=1;
        for(ll i =1;i<=maxx;i++) //枚举同种最大数量
        {
            ms[i]+=ms[i-1];
            if(ms[i]!=0)
            {
                s=ms[i];c=i;
                ll g=__gcd(s,c);
                s/=g;c/=g;
                if(as*c<ac*s)
                {
                    as=s;
                    ac=c;
                }
            }
        }
        cout<<as<<"/"<<ac<<endl;

    }
}


7.Gym - 102821B

题意:给出两个矩形,两个矩形可以平移和旋转,问能够包含下这两个矩形的最小多边形的面积。

思路:分四种情况讨论,然后输出最小的面积即可。

#include <bits/stdc++.h>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <stdio.h>
#include <map>
#include <iomanip>
#include <string>
#include <cstring>
#include <string.h>
using namespace std;
bool cmp(int x,int y)
{
    return x>y;
}
int main()
{
    int t,num=0;
    for(cin>>t;t;t--)
    {num++;
       double a,b,c,d;
       cin>>a>>b>>c>>d;
       double k1,k2,k3,k4;
       if(b<=d){
      k1= d*(a+c)-(d-b)*a*0.5;
       }
       if(b>d){
      k1=b*(a+c)-(b-d)*c*0.5;
       }//长贴长
       if(a<=c){
        k2=c*(b+d)-(c-a)*b*0.5;
       }
       if(a>c){
        k2=a*(b+d)-(a-c)*d*0.5;
       }//宽贴宽
       if(b>c){
        k3=b*(a+d)-(b-c)*d*0.5;
       }
       if(b<=c){
        k3=c*(a+d)-(c-b)*a*0.5;
       }//长贴宽
       if(a>d){
        k4=a*(b+c)-(a-d)*c*0.5;
       }
       if(a<=d){
        k4=d*(b+c)-(d-a)*b*0.5;
       }//宽贴长
       double ans=min(min(k1,k2),min(k3,k4));
       cout<<"Case "<<num<<": "<<fixed<<setprecision(1)<<ans<<endl;
            }
    return 0;
}

8.Gym - 102821H

题意:n是提交的次数,m是题数,第二行是n次提交的时间,第三行是每道题提交的次数,交错一次会罚时20分钟,fish能够修改题的题号和提交结果,问修改后最好的结果的罚时。

思路:将时间和每道题的提交次数升序排列,让提交次数少的去使用更少的时间。

#include <bits/stdc++.h>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <stdio.h>
#include <map>
#include <iomanip>
#include <string>
#include <cstring>
#include <string.h>
using namespace std;
bool cmp(int x,int y)
{
    return x>y;
}
int main()
{
    int t,num=0;
    for(cin>>t;t;t--)
    {num++;
        int n,m,a[100010],c[15];
       scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        for(int i=1;i<=m;i++){
           scanf("%d",&c[i]);
        }
        int ans=0;
        sort(a+1,a+n+1);
        sort(c+1,c+m+1);
        int ac=1;
        for(int i=1;i<=n;i++){
            if(c[ac]==1){
                ans+=a[i];
                ac++;
            }
            else {
                c[ac]--;//题目的提交次数为1的时候才能改为AC
                ans+=20;
            }
        }
        cout<<"Case "<<num<<": "<<ans<<endl;

            }
    return 0;
}

9.Gym - 103055C

题意:给你八个点的坐标,问能否组成一个正方体。

思路:正方体只有三种长度,边长,面对角线和体对角线,只要有且只有三种长度不同的长度即可证它是正方体,特殊情况:若两个面重合的话体对角线就为0了,所以要是三种长度不为0且不同。

#include <bits\stdc++.h>

using namespace std;
struct point
{
    int x,y,z;
}point1[8];
bool cmp(int x,int y)/*降序*/
{
    return x>y;
}
int main()
{
    int t;
     //freopen("in.txt","r",stdin);
    for(cin>>t;t;t--)
    {
        long long value[200]={0},count1=0;
           int ans=0;
        for(int i=0;i<8;i++)
        {
            cin>>point1[i].x>>point1[i].y>>point1[i].z;
        }
        for(int i=0;i<8;i++)
        {
            for(int j=0;j<8;j++)
            {
                if(i!=j)
                {
                    long long x=(point1[i].x-point1[j].x)*(point1[i].x-point1[j].x);
                    long long y=(point1[i].y-point1[j].y)*(point1[i].y-point1[j].y);
                   long long z=(point1[i].z-point1[j].z)*(point1[i].z-point1[j].z);
                    if(x+y+z==0)
                    {
                        cout<<"NO"<<endl;

              goto o;
                    }
                    value[count1]=x+y+z;
                    count1++;
                }
            }
        }
        sort(value,value+200,cmp);
        for(int i=1;i<56;i++)
        {
            if(value[i]==value[i-1])
            {
                continue;
            }
            else
            {
                ans++;
            }
        }
        if(ans==2)
        {
            cout<<"YES"<<endl;
        }
        else
        {
            cout<<"NO"<<endl;
        }
      o:;//goto可以暴力的跳出循环,无论它有几重,都可以跳到标记点。
    }
    return 0;
}

总结感受

训练了五天,第一天:读题读的有点拉跨了,A题题意没理解好,H题没有读明白,而且状态也不是很好,一边读一边在怀疑自己和题目,感觉越读越离谱,到最后还真就是个离谱的题目。

第二天:找水题找的也不是很准,庆幸的是题目没读错(/捂脸),速度还不是很快。

第三天:k题找的挺快的但是中间代码换我来打了,然后我给搞砸了,没看清队友的代码思路,导致我们中间卡了很长时间(是在下的锅没错了)。。。

第四天:这天就过了一题,但这次找水题very的快,A题那道日期的题应该也能做出来的,但是好不容易打出来竟然超时了,还是得提高呀。

第五天:今天A题应该能更快的做出来的,但是把他想麻烦了,幸好我们G题wa了一次就出了,之后又很快的做出了A题,不然今天也是有点悬。

训练了五天之后,感觉自己读题的速度和题意的把握程度还是要提高,而且在读完题之后感觉自己就没用了,思路也想不出来,这一点也要慢慢的改变,不然最后两小时只能坐吃等死。

现在的重点就是快且稳的先把水题给干掉,这对于大一的我们来说是最重要的,为此要更快的阅读,加油!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

killer_queen4804

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值