奋斗群群赛---15,16

来源:互联网 发布:战地4淘宝怎么搜 编辑:程序博客网 时间:2024/06/16 08:45

奋斗群群赛—15,16

  • 奋斗群群赛1516
  • 群赛15
    • T1Fashion in Berland
      • 题目位置
      • 题意
      • AC代码
    • T2s-palindrome
      • 题目位置
      • 题意
      • AC代码
    • T3 Exponential notation
      • 题目位置
      • 题意
      • AC代码
    • T4Swaps in Permutation
      • 题目位置
      • 题意
      • AC代码
    • T5Xor-sequences
      • 题目位置
      • 题意
      • 思路
      • AC代码
      • 反思
    • T6Couple Cover
      • 题目位置
      • 题意
      • 思路
      • AC代码

群赛15:

T1:Fashion in Berland

题目位置:

T1位置所在

题意:

就是给你一个 01串,让你找出是否这个串只有一个 0 ,如果是,输出”YES”,不然就是输出”NO”!但是只有一个纽扣的时候要进行特判,必须是只有1的串(给题意杀了……)

AC代码:

#include <bits/stdc++.h>using namespace std;int main(){    int n,ans=0;    scanf("%d",&n);    if(n==1)    {        int y;        scanf("%d",&y);        if(y==0)            cout<<"NO";        else            cout<<"YES";        return 0;    }    for(int i=1; i<=n; i++)    {        int x;        scanf("%d",&x);        if(x==0)            ans++;    }    if(ans==1)        cout<<"YES";    else        cout<<"NO";    return 0;}

T2:s-palindrome

题目位置:

T2位置所在

题意:

就是问你这一串英文字母是不是能够在”镜子”的照应之下,是和原来是对应一半相等的?
其实就是一个大模拟!

AC代码

#include <bits/stdc++.h>using namespace std;const int N=1005;char s[N];int check(char x,char y){    if(x=='A'&&y=='A')        return 1;    if(x=='H'&&y=='H')        return 1;    if(x=='I'&&y=='I')        return 1;    if(x=='M'&&y=='M')        return 1;    if(x=='O'&&y=='O')        return 1;    if(x=='T'&&y=='T')        return 1;    if(x=='U'&&y=='U')        return 1;    if(x=='V'&&y=='V')        return 1;    if(x=='W'&&y=='W')        return 1;    if(x=='X'&&y=='X')        return 1;    if(x=='Y'&&y=='Y')        return 1;    if(x=='o'&&y=='o')        return 1;    if(x=='v'&&y=='v')        return 1;    if(x=='w'&&y=='w')        return 1;    if(x=='x'&&y=='x')        return 1;    if(x=='b'&&y=='d')        return 1;    if(x=='d'&&y=='b')        return 1;    if(x=='p'&&y=='q')        return 1;    if(x=='q'&&y=='p')        return 1;    return 0;}int main(){    //string s;    scanf("%s",s+1);    int len=strlen(s+1);    int ans=0;    for(int i=1; i<=len/2; i++)    {        ans+=check(s[i],s[len-i+1]);    }    if(len%2==1)    {        int l=len/2+1;        ans+=check(s[l],s[l]);        if(ans==1+len/2)            cout<<"TAK";        else            cout<<"NIE";    }    else    {        if(ans==len/2)            cout<<"TAK";        else            cout<<"NIE";    }    return 0;}

T3: Exponential notation

题目位置:

T3位置所在

题意:

就是让你讲一个数字,变成 x*pow(10,n)形式,比如

 input16 output1.6E1 input01.23400 output1.234 input.100 output1E-1 input100. output1E2

AC代码:

#include <bits/stdc++.h>using namespace std;const int N=1000005;char s[N];int main(){    scanf("%s",s+1);    int n=strlen(s+1);    int sep=n+1,sta=1,end=n;    int flag=0;    for(int i=1; i<=n; i++)    {        if(s[i]=='.')            sep=i;        if((s[i]=='0'||s[i]=='.')&&flag==0)        {            sta=i+1;        }        else if (s[i]>'0'&&s[i]<='9')        {            flag=1;        }    }    flag=0;    for(int i=n; i>=1; i--)    {        if((s[i]=='0'||s[i]=='.')&&flag==0)        {            end=i-1;        }        else if (s[i]!='0')        {            flag=1;        }    }    //cout<<sep<<" "<<sta<<" "<<end<<endl;    int r=end-sep,l;    if(sep<sta)    {        l=sep-sta;    }    else    {        l=sep-sta-1;    }    int p=0;    for(int i=sta+1; i<=end; i++)    {        if(s[i]!='0')            p=1;    }    printf("%c",s[sta]);    if(p==1) cout<<'.';    if(p)    {        for(int i=sta+1; i<=end; i++)        {            if(s[i]!='.')                printf("%c",s[i]);        }    }    if(l!=0)    {        printf("E");        printf("%d",l);    }}

T4:Swaps in Permutation

题目位置

T4位置所在

题意:

给一个数列,现在可以交换ai和bi,问能得到的最大的字典序的数列是什么
还有就是a->b,b->c那么 a->c啊!所以就是可以用到一个并查集的工作!

AC代码:

#include <iostream>#include <stdio.h>#include <cstring>#include <vector>#include <algorithm>#include <map>#include <queue>using namespace std;const int N=1000005;int fa[N],a[N];int n,m;vector<int>  value[N];vector<int>  order[N];int find(int a){    return fa[a] ==a ?a : fa[a]= find(fa[a]);}int add(int x,int y){    fa[find(x)] = find(y);}int main(){    //greater<int> ¾ÍÊǽ«Öµ´ÓСµ½´ó½øÐÐÒ»´Î ÅÅÐò!    int n,m;    scanf("%d%d",&n,&m);    for(int i=1; i<=n; i++)        fa[i]=i;    for(int i=1; i<=n; i++)    {        scanf("%d",&a[i]);    }    for(int i=1; i<=m; i++)    {        int x,y;        scanf("%d%d",&x,&y);        add(x,y);    }    for(int i=1; i<=n; i++)    {        int root=find(i);        order[root].push_back(i);        value[root].push_back(a[i]);    }    for(int i=1; i<=n; i++)    {        sort(value[i].begin(),value[i].end(),greater<int>());        sort(order[i].begin(),order[i].end());        for(int j=0; j<value[i].size(); j++)        {            a[order[i][j]]=value[i][j];        }    }    for(int i=1; i<=n; i++)        printf("%d ",a[i]);    return 0;}

T5:Xor-sequences

题目位置:

T5位置所在

题意:

给定序列,从序列中选择k(1≤k≤1e18)个数(可以重复选择),使得得到的排列满足xi与xi+1异或的二进制表示中1的个数是3的倍数。问长度为k的满足条件的 序列有多少种?

思路:

矩阵快速幂!

AC代码:

#include <iostream>#include <stdio.h>#include <algorithm>#include <cstring>#define ll long longusing namespace std;const int mod=1000000007;ll m,a[1005];int n,ans;struct number{    int edge[110][110];    number()    {        memset(edge,0,sizeof(edge));    }} ANS,K,FIN;number operator * (number ANS,number K){    number res;    for(int i=1; i<=n; i++)        for(int j=1; j<=n; j++)        {            for(int k=1; k<=n; k++)                res.edge[i][j]=(ll)(res.edge[i][j]+(ll)ANS.edge[i][k]*K.edge[k][j]%mod)%mod;        }    return res;}int main(){    scanf("%d%I64d",&n,&m);    for(int i=1; i<=n; i++)    {        scanf("%I64d",&a[i]);    }    for(int i=1; i<=n; i++)        for(int j=1; j<=n; j++)        {            ll x;            int cnt=0;            x=a[i]^a[j];            while(x)            {                cnt+=x&1;                x>>=1;            }            if(cnt%3==0)                K.edge[i][j]=1;        }    m--;    for(int i=1; i<=n; i++)        ANS.edge[i][i]=1;    while(m)    {        if(m&1)        {            ANS=ANS*K;        }        K=K*K;        m>>=1;    //  cout<<m<<endl;    }    for(int i=1; i<=n; i++)        for(int j=1; j<=n; j++)        {            ans=(ans+ANS.edge[i][j])%mod;        }    printf("%d\n",ans%mod);    return 0;}

反思:

就是在看见了1e18的数据的时候就是想到一定是用log的算法来完成它,所以就是要想到快捷的方法,于是就是矩阵快速幂!

T6:Couple Cover

题目位置:

T6位置所在

题意:

就是问你在一个序列里面,有多少对数的积是大于等于p 的?
有多组询问!

思路:

如果简单的枚举会十分的困难,肯定会TLE,但是其实这道题目的数据会有许多重复的,所以只要用一个桶来装这些数字,在预处理一下就好了,(正难则反)只要看有多少是小于p的而且有多少是总的,减一下就好了!

AC代码:

#include <bits/stdc++.h>using namespace std;const int N=3000005;long long n;long long num[N],qus[N];int main(){    int m;    scanf("%I64d",&n);    for(int i=1; i<=n; i++)    {        int x;        scanf("%d",&x);        num[x]++;    }    for(int i=1; i*i<N; i++)        for(int j=i; i*j<N; j++)        {            if(i==j)                qus[i*i]+=num[i]*(num[i]-1);            else                qus[i*j]+=num[i]*num[j]*2;        }    for(int i=0; i<N; i++)    {        qus[i]+=qus[i-1];    }    //que[N-1]?a¡Á????a     scanf("%d",&m);    for(int i=1; i<=m; i++)    {        int x;        scanf("%d",&x);        long long ans=n*(n-1)-qus[x-1];        printf("%I64d\n",ans);    }}
原创粉丝点击