czl蒻蒟的OI之路3

  • XJOI奋斗群蒻蒟群群赛4 RANK排名3
      • T1Arpa and a research in Mexican wave WA一次后AC
          • 题意
          • 分析过程
          • 给出题解
      • T2Arpa and an exam about geometry 已AC
          • 题意
          • 分析过程
          • 给出题解
      • T3Five Dimensional Points 已AC
          • 题意
          • 分析过程
          • 给出题解
      • T4Little Elephant and LCM WA后两次已AC
          • 题意
          • 分析过程
          • 给出题解
      • T5Polycarpus Dice WA后三次已AC
          • 题意
          • 分析过程
          • 给出题解
      • 补群赛3 T5Bank Hackingn次WA后AC
          • 题意
          • 分析过程
          • 给出题解
      • 蒻蒟总结

—>XJOI奋斗群(蒻蒟群)群赛4<— RANK排名3

T1:Arpa and a research in Mexican wave (WA一次后AC)

题意:

给你三个数,分别是人群的人数n,每次最大能站起的人数k,和询问的时间t。让你求在时间t的点,站起来的人数。

分析过程:

简单来说,就是把从第一个人站起开始到最后一个人坐下这段时间分为3段计算,第一段,当t<=k时,能站起来的人数就是t,当t在k和n之间时,能站起来的人数是k,当t大于n时,能站起来的人数就是n+k-t。

给出题解:
#include
using namespace std;

long long int n,k,t,ans;
int main()
{
    cin>>n>>k>>t;
    if(t<=k)ans=t;
    else if(t>k&&t<=n)ans=k;
    else if(t>n)ans=n+k-t;
    cout<

T2:Arpa and an exam about geometry (已AC)

题意:

给你三个点a,b,c,问你能否寻找一个点和一个角度,使a转到b的位置,b转到c的位置。

分析过程:

因为这题是旋转,所以a,b,c,三点一定要共圆,所以先排除三点共线的情况。然后由于a要转到b,b要转到c,所以弧ab和弧bc的值要相等,换句话说,就是ab和bc的距离要相等,所以只要判断一下这个,就能够AC了。

给出题解:
#include<bits/stdc++.h>
using namespace std;

long long int ax,ay,bx,by,cx,cy;
double k1,k2,k3;
int main()
{
    long long int dis_ab,dis_ac,dis_bc,max_dis=-1;
    cin>>ax>>ay>>bx>>by>>cx>>cy;
    dis_ab=(ax-bx)*(ax-bx)+(ay-by)*(ay-by);
    k1=(double)(ax-bx)/(ay-by);
    dis_ac=(ax-cx)*(ax-cx)+(ay-cy)*(ay-cy);
    k2=(double)(ax-cx)/(ay-cy);
    dis_bc=(bx-cx)*(bx-cx)+(by-cy)*(by-cy);
    k3=(double)(bx-cx)/(by-cy);
//  cout<
    if(k1==k2&&k2==k3)cout<<"No";
    else 
    {
        if(dis_ab==dis_bc)cout<<"Yes";
        else cout<<"No";
    }
    return 0;
}

T3:Five Dimensional Points (已AC)

题意:

看起来很厉害的五维空间,实际上就是一个5n的矩阵。给你一个n,然后构建一个5n的矩阵。让你判断有哪些的点的角度是90°的,角度的计算方法题中已经给出了(这里也有点解释不清),并且输出每个点的向量值。

分析过程:

这题看起来很高能,什么五维空间,但实际分析起来,并不是特别难。先按照他的方法遍历每两个点之间的角度,如果角度为90°,ans就++,然后分别计算出每个好角度的向量值并输出。具体的判断两个点的角度的方法,只需用一个bool型数组,如果算出的值大于1,就返回0,其余的都返回1,(因为arc(0)=90°)。

给出题解:
#include
using namespace std;
long long int  a[105][5];
int n,Ans,b[105];
bool check(int i)
{
    for (int j=1;j<=n;j++)
        for (int k=j+1;k<=n;k++)
            if (i!=j&&i!=k)
            { 
                long long int tmp=0;
                for (int l=1;l<=5;l++) 
                    tmp+=(a[j][l]-a[i][l])*(a[k][l]-a[i][l]);
                if (tmp>0) return 0;
            }
    return 1;
}
int main()
{
    scanf("%d",&n);
    if (n>11)
    {
        printf("0");
    }
    else
    {
        for (int i=1;i<=n;i++)
        for (int j=1;j<=5;j++)
            scanf("%I64d",&a[i][j]);
        for (int i=1;i<=n;i++)
        {
            Ans+=b[i]=check(i);
        }
        printf("%d\n",Ans);
        for (int i=1;i<=n;i++)
        if (b[i])
        {
            printf("%d\n",i);
        }
    }
} 

T4:Little Elephant and LCM (WA后两次已AC)

题意:

给你n个骰子,然后每个骰子有d[i]面,给你一个a,a表示这n个骰子所扔的点数和
然后问你,每一个骰子有多少个数不能投掷到。

分析过程:

对于一个骰子,先求出其余所有筛子能够得到的最大值之和和最小值之和,然后根据最大值之和、最小值之和就能求出每个骰子不可能出现的点数。
如果其余所有的骰子都取最小值1,则最小值之和为n-1,当前骰子应取x=A - (n - 1),当前骰子的最大取值就是x,若d[i]>x, 则从x+1~d[i]之间的数都不会取到,共有d[i]-x个;如果其余所有的骰子都去最大值d[i],则最大值之和为sum - d[i],当前骰子的应取y=A - (sum - d[i]),最小取值就是y,若y > 0,则从1~y-1之间的数都不可能取到,共有y-1个;二者加起来就是最终的答案。

给出题解:
#include
#define maxn 1000050
#define LL long long int
using namespace std;

int main()
{
    LL n,ans;
    LL d[maxn];
    LL max_ans=0;
    cin>>n>>ans;
    for(int i=1;i<=n;i++)
    {
        cin>>d[i];
        max_ans=max_ans+d[i];
    }
//  cout<
    if(n==1)cout<1]-1;
    else 
    {
        for(int i=1;i<=n;i++) 
        {
        d[i]=max((LL)0,d[i]-ans-1+n)+max((LL)0,ans-max_ans+d[i]-1);
        cout<" ";
        }
    }
    return 0;
}

T5:Polycarpus’ Dice (WA后三次已AC)

题意:

给你一个数列a1,a2…,an,让你求在另一个数列b1,b2..,bn(bi满足1<=bi<=ai)中有几个序列的最大值和它的最小公倍数相同。

分析过程:

既然该序列的最小公倍数和它的最大值相同,则所有数都应该是最大值的因数,所以只要从最大数开始向1枚举,后面的数只能为它的因数,所以再列举最大数的因数,计算后面的数可以填的个数,再相乘,就能得到答案。

给出题解:
#include
using namespace std;
const int mod=1e9+7;
long long int cnt[100000];
long long int powermod(long long int a,long long int b)
{
    long long int ans=1;
    while(b)
    {
        if(b&1) ans=ans*a%mod;
        a=a*a%mod;
        b=b/2;
    }
    return ans;
}
int main()
{
    long long int n;
    long long int j;
    long long int ans=0,basic;
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>cnt[i];
    }
    sort(cnt+1,cnt+n+1);
    for(int i=1; i<=cnt[n]; i++)
    {
        vector <int> a;
        for(j=1; j*j<=i; j++)
        {
            if(i%j==0)
            {
                a.push_back(j);
                if(j*j!=i) a.push_back(i/j);
            }
        }
        sort(a.begin(),a.end());
        int b,c=1;
        basic=1;
        for(j=1; j1,cnt+n+1,a[j])-cnt;
            basic=basic*powermod(j,b-c)%mod;
            basic=basic%mod;
            c=b;
        }
        ans=(ans+basic*(((powermod(j,n-c+1)-powermod(j-1,n-c+1)+mod))%mod))%mod;
    }
    cout<

补:群赛3 T5:Bank Hacking(n次WA后AC)

题意:

给你n个银行以及n-1个电线,将两个银行互相连接,并且每个银行都有一定的实力值。用一条电线相连的两个银行称为相邻,用两条电线相连的两个银行称为半相邻。每当一个银行被黑掉时,相邻与半相邻的银行实力都会+1.

分析过程:

简单分析一下可知,黑掉第一个银行后,相邻的银行下一次会被黑掉,而半相邻的银行则是会变成相邻的银行。故选择第一个黑的银行后,相邻的银行实力会+1,其余的都+2。知道这个,题目就好懂了,只需判断最大数与最大数-1的个数,进行特判即可。

给出题解:
#include
using namespace std;
const int inf=1e9+10;
vector <int> a[1000000];
int str[10000000],x,y;
int main(){
    int n,m=-inf,temp;
    int cnt1=0,cnt2=0,cnt;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>str[i];
        m=max(m,str[i]);
    }
    for(int i=1;i<=n-1;i++)
    {
        cin>>x>>y;
        a[x].push_back(y);
        a[y].push_back(x);
    }
    for(int i=1;i<=n;i++)
    {
        if(str[i]==m)
        {
            cnt1++;
            temp=i;
        }
        else if(str[i]==m-1)cnt2++;
    }
    if(cnt1==1)
    {
        cnt=0;
        for(int i=0;iif(str[a[temp][i]]==m-1) cnt++; 
        }
        if(cnt==cnt2) cout<else cout<1;
    }
    else{
        bool flag=false;
        for(int i=1;i<=n;i++){
            int cnt=0;
            if(str[i]==m) cnt++;
            for(int j=0;jif(str[a[i][j]]==m) cnt++;
            }
            if(cnt==cnt1) flag=true;
        }
        if(flag) cout<1;
        else cout<2;
    }
    return 0;
}

蒻蒟总结:

今天距离AK还有一点距离,但比昨天要好一些了。最后一题已经有了较为成型的想法,但是还有一些细节没有注意到。但是今天的A B题刷的比较慢,随着训练的时间增长,对于简单题目的速度以及到位程度更加需要提升,不能把罚分浪费在这些简单的题目上。明天还是有比赛的,然而前几次的题目还有一题没有补完,今日的第五题也没有AC,明天要加倍努力了(或许只是周六不想跑圈罢了吧~)。

你可能感兴趣的:(蒟蒻OI之路)