ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Codeforces Round #749 (Div.1+Div.2)A-D题解

2021-10-19 21:01:16  阅读:201  来源: 互联网

标签:cout int 题解 合数 Codeforces cin vis 749 include


A. Windblume Ode
题意:就是从n个数里面挑p(要求最大)个数的和为合数,输出所挑选的数的下标,顺序随便
思路:p的可能值只有n or n-1,如果所有加起来的和为合数,输出n,否则,在奇数中挑一个数减去,使得和为合数,
证明:假设偶数有a个,奇数有b个,a个偶数相加肯定为合数,
(1)如果b是偶数,则奇数可以两两配对,所以最后的和为偶数,肯定为合数
(2)如果b为奇数,那么最后的和可能为合数,可能不是,如果不是,和肯定为奇数,所以需要减去一个奇数,使得和为合数
代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
typedef pair<double,double> pdd;
const int inf=0x3f3f3f3f;
const int maxn=1e5+10;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        int a[200];
        int sum=0;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            sum+=a[i];
        }
        int flag=0;
        for(int i=2;i*i<=sum;i++)
        {
            if(sum%i==0)
            {
                flag=1;
                break;
            }
        }
        if(flag)
        {
            cout<<n<<endl;
            for(int i=1;i<=n;i++)
            {
                cout<<i<<" ";
            }
            cout<<endl;
        }
        else
        {
            int k=0;
            cout<<n-1<<endl;
            for(int i=1;i<=n;i++)
            {
                if(a[i]%2&&k==0)
                {
                    int f=0;
                    for(int j=2;j*j<=sum-a[i];j++)
                    {
                        if((sum-a[i])%j==0)
                        {
                            f=1;
                            break;
                        }
                    }
                    if(f)
                    {
                        k=1;
                        continue;

                    }
                    else
                    {
                        cout<<i<<" ";
                    }
                }
                else
                {
                    cout<<i<<" ";
                }
            }
            cout<<endl;
        }
    }
}

B. Omkar and Heavenly Tree
题意:有一个n节点的图,有m个限制,输入限制a b c,代表a c中间的简单路径中不能有b节点,(n>m)构造这个图
思路:因为n>m所以肯定有一个节点没有任何限制,我们可以把它放中间,其他点围成一圈,就可以了,这样点和点之间都是这个没有任何限制的点,
代码

#include<bits/stdc++.h>
using namespace std;
int vis[100005];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,m;
        cin>>n>>m;
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=m;i++)
        {
            int a,b,c;
            cin>>a>>b>>c;
            vis[b]=1;
        }
        int id=0;
        for(int i=1;i<=n;i++)
        {
            if(vis[i]==0)
            {
                id=i;
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(id==i)continue;
            cout<<id<<" "<<i<<endl;
        }
    }
}

C. Omkar and Determination
题意:有一个n×m图,有些格子被填充,有些空着,空单元格可通过,向上或向左移动走出边界,所以我们可以通过原图确定一个新图,上面标记着那些单元个可以走出边界那些不行,这个新图也可以反推出原图,如果这个新图反推出的图是唯一的,则称这个原图是可确定的,现在问你由Xn,Xn+1,··· Xn+m列组成的图是不是可确定的
思路:如果一个空单元格走不出边界,那么这个单元格对应的新图上走不出去,那么这个单元格也可以是填充的,所以这个点反推回来会有两种情况,所以我们要统计原图上空单元格走不出去的点,利用前缀和,如果q[l]=q[r]代表l+1~r间没有不符合的点,输出YES,否则输出NO,并且,如果查询范围l=r直接输出YES
代码

#include<iostream>
#include<algorithm>
#include<map>
#include<vector>
#include<cstring>
using namespace std;
int vis[1000005];
int q[1000005];
char s[1000005];
char c[1000005];
int main()
{
    int n, m;
    cin >> n >> m;
    int cnt = 0;
    for (int i = 0; i < n; i++)
    {
        cin >> c;
        for (int j = 0; j < m; j++)
        {
            if (i > 0 && j > 0)
            {
                if (s[j] == 'X' && c[j - 1] == 'X')
                {
                    vis[j]++;
                }
            }
        }
        strcpy(s, c);
    }
    for (int i = 1; i < m; i++)
    {
        q[i] = q[i - 1] + vis[i];
    }
    int t;
    cin >> t;
    while (t--)
    {
        int l, r;
        cin >> l >> r;
        if (l == r)cout << "YES" << endl;
        else
        {
            r--,l--;
            if (q[r] == q[l])
                cout << "YES" << endl;
            else
            {
                cout << "NO" << endl;
            }
        }
    }
}

D. Omkar and the Meaning of Life
题意:你可以查询不超过2*n次,每次查询输出a1~an,设sj=aj+pj;如果s中有重复的,会返回第一个重复值的下标,求p数组(p数组是n的一个排列,里面每个数在1到n之间,不重复)
思路:
在这里插入图片描述
每次查询可以得到其它数与pn的差距
在这里插入图片描述
左边得到比pn小的数的差距,右边得到比pn大的数的差距
代码

#include<bits/stdc++.h>
using namespace std;
int d[110];
int n;
int main()
{
    cin>>n;
    for(int i=2;i<=n;i++)
    {
        cout<<"? ";
        for(int j=1;j<n;j++)
        {
            cout<<i<<" ";
        }
        cout<<1<<endl;
        fflush(stdout);
        int x;
        cin>>x;
        d[x]=1-i;//与pn的差距
    }
    for(int i=2;i<=n;i++)
    {
        cout<<"? ";
        for(int j=1;j<n;j++)
        {
            cout<<1<<" ";
        }
        cout<<i<<endl;
        fflush(stdout);
        int x;
        cin>>x;
        d[x]=i-1;
    }
    int mi=1;
    for(int i=1;i<=n;i++)
    {
        if(d[mi]>d[i])
        {
            mi=i;
        }
    }
    int ans=-d[mi]+1;
    cout<<"! ";
    for(int i=1;i<=n;i++)
    {
        cout<<d[i]+ans<<" ";
    }
    fflush(stdout);
}

标签:cout,int,题解,合数,Codeforces,cin,vis,749,include
来源: https://blog.csdn.net/qq_54026781/article/details/120853677

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有