2020牛客暑期多校训练营(第四场) 个人做题记录

F.Finding the Order

大意是说有两条平行线AB、CD,给出AC、AD、BC、BD的长度,要求判断是 A B ∣ ∣ C D AB||CD ABCD还是 A B ∣ ∣ D C AB||DC ABDC(就是判断CD两点的位置关系)。
2020牛客暑期多校训练营(第四场) 个人做题记录_第1张图片
读入之后分情况讨论即可(详见代码)

#include
#include
#include
#include
#include
#include
#define MOD 1000000007
using namespace std;
int main()
{
    int t,ac,ad,bc,bd;
    int flag;
    scanf("%d",&t);
    while(t--)
    {
        flag=0;
        scanf("%d%d%d%d",&ac,&ad,&bc,&bd);
        if((bc>bd)&&(bd>ac)&&(ac>ad)) flag=1;
        else if(bc>bd&&bc>ac) flag=1;
        else if(bc>ac&&ad>bd) flag=1;
        else if(ad>bd&&ad>ac) flag=1;
        else if((ad>ac)&&(ac>bd)&&(bd>bc)) flag=1;
        else if((bd>bc)&&(bc>ad)&&(ad>ac)) flag=2;
        else if(bd>bc&&bd>ad) flag=2;
        else if(bd>ad&&ac>bc) flag=2;
        else if(ac>bc&&ac>ad) flag=2;
        else if((ac>ad)&&(ad>bc)&&(bc>bd)) flag=2;
        if(flag==1)printf("AB//CD\n");
        else printf("AB//DC\n");
    }
    return 0;
}

**H.Harder Gcd Problem **
大概意思是对于每组数据,给出一个n,求在1~n中最多能找出多少对数(x,y)使得gcd(x,y)不等于1,每个数只能用一次,输出最多对数以及每一对(x,y)

猜测除了1和大于n/2的质数之外至多只有一个数无法配对,很幸运结论是正确的。
线性筛找出 1 1 1 ~ 2 ∗ 1 0 5 2*10^5 2105的质数,然后对 2 2 2 ~ n n n的每个数分解质因数,将每个数加入其最大的质因子对应的vector中(如果这个数直接是质数则不加入)。然后将 1 1 1 ~ n n n范围的每个质数加入对应vector中。
寻找时则从 n n n枚举到 1 1 1,若当前vector中有2或更多数则拿出最后两个数(保证优先匹配掉质数)匹配存入答案数组,否则若有一个数则去掉其最大质因子,将其放入次大质因子对应的vector中(若去掉了所有质因子则丢弃这个数)。

(更新) 看了一蛤题解,正解是从大到小扫描枚举所有质数,判断1~n范围内还有几个没有被标记的该质数的倍数,如果是偶数个则一对一对匹配,否则保留2*该质数的值(是偶数),这样最后扫描到2时一定能全部匹配。
而我的做法正好跟正解的效果一样

#include
#include
#include
#include
#include
#include
#define MOD 1000000007
using namespace std;
const int p=200000;
int flag[p+5];
int prime[p+5],cot;
vector<pair<int,int> > ans;
vector<vector<int> > ppp[200005];
vector<int>temp;
void find_prime()
{
    for(int i=2;i<=p;i++)
    {
        if(!flag[i]) prime[++cot]=i;
        for(int j=1;j<=cot&&i*prime[j]<=p;j++)
        {
            flag[i*prime[j]]=1;
            if(i%prime[j]==0)break;
        }
    }
}
int main()
{
    find_prime();
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=2;i<=n;i++)
        {
            int now=i;
            vector<int>().swap(temp);
            temp.push_back(i);
            for(int j=1;j<=168;j++)
            {
                if(now%prime[j]==0)
                {
                    temp.push_back(prime[j]);
                    while(now%prime[j]==0)
                    {
                        now/=prime[j];
                    }
                }
                if(now==1) break;
            }
            if(now!=1) temp.push_back(now);
            if(temp[temp.size()-1]!=temp[0])ppp[temp[temp.size()-1]].push_back(vector<int>(temp));
        }
        for(int i=1;i<=cot&&prime[i]<=n;i++)
        {
            int now=i;
            vector<int>().swap(temp);
            temp.push_back(prime[i]);
            temp.push_back(prime[i]);
            ppp[temp[temp.size()-1]].push_back(vector<int>(temp));
             
        }
        for(int i=n;i;i--)
        {
            int pz=ppp[i].size();
            while(pz>1)
            {
                ans.push_back(make_pair(ppp[i][pz-1][0],ppp[i][pz-2][0]));
                ppp[i].erase(ppp[i].begin()+pz-2,ppp[i].end());
                pz-=2;
            }
            if(pz)
            {
                vector<int>().swap(temp);
                temp=ppp[i][0];
                ppp[i].erase(ppp[i].begin(),ppp[i].end());             
                temp.erase(temp.begin()+temp.size()-1,temp.end());
                if(temp.size()!=1)
                {
                    ppp[temp[temp.size()-1]].push_back(vector<int>(temp));
                }
            }
        }
        printf("%d\n",ans.size());
        for(int i=0;i<ans.size();i++)
        {
            pair<int,int> s;
            s=ans[i];
            printf("%d %d\n",s.first,s.second);
        }      
        vector<pair<int,int> >().swap(ans);
    }
    return 0;
}

你可能感兴趣的:(牛客网,题解(按比赛))