Codeforces Round #708 (Div. 2) A--C2andE

A 题目链接 这里
题解:签到题,这个题和之前某一场的b描述是一样的,都是找不在当前数里的最小值,这个排个序,把相同的扔最后可以得到答案。

    #include<bits/stdc++.h>
    #define ll long long
    #define pr pair<ll,ll>
    #define ios ios::sync_with_stdio(false)
    #define CRL(a) memset(a,0,sizeof a)
     
    using namespace std;
     
    const int maxn = 1e5 + 5;
     
    int x[maxn];
    int y[maxn];
    int main()
    {
        ios;
        int t;
        cin >> t;
        while(t--)
        {
    		int n;
    		cin >> n;
    		for (int i = 1; i <= n;i++)
    		{
    			cin >> x[i];
    		}
    		sort(x + 1, x + 1 + n);
    		x[0] = -5;
    		int cnt = 0;
    		for (int i = 1; i <= n;i++)
    		{
    			if(x[i]!=x[i-1])
    			{
    				cout << x[i] << " ";
    			}
    			else 
    			{
    				y[++cnt] = x[i];
    			}
    		}
    		for (int i = 1; i <= cnt;i++)
    		{
    			cout << y[i] << " ";
    		}
    		cout << endl;
    	}
    }

B 题目链接 这里
题解:这个题目让我们找数组的划分,且数组里的每个数和他的下一个数相加都是一个数m的倍数,让我们求这样的划分最少有几个。我们可以桶排来找每个数有几个,但数据范围是1e9,我们需要进行取模,而且如果这个数本身就是m的倍数,我们可以把所有这样的数扔在一起形成一个划分。剩下的数我们可以找这个数与m的差,来确定这个划分中有几个数,这里有几个细节是需要注意下的,具体看代码。

    #include<bits/stdc++.h>
    #define ll long long
    #define pr pair<ll,ll>
    #define ios ios::sync_with_stdio(false)
    #define CRL(a) memset(a,0,sizeof a)
     
    using namespace std;
     
    const int maxn = 1e5 + 5;
     
    int x[maxn];
    int y[maxn];
    int main()
    {
        ios;
        int t;
        cin >> t;
        while(t--)
        {
            int n, m;
            cin >> n >> m;
            memset(x, 0, sizeof x);
            memset(y, 0, sizeof y);
            int cnt = 0;
            int ans = 0;
            for (int i = 1; i <= n;i++)
            {
                int a;
                cin >> a;
                if(a%m)
                    x[++cnt] = a % m, y[a % m]++;
                else
                    ans = 1;
            }
            for (int i = 1; i <= cnt;i++)
            {
                if(y[x[i]])
                {
                    int b = m - x[i];
                    if(y[b])
                    {
                        if(y[x[i]]>y[b])
                            y[x[i]] = y[x[i]] - y[b] - 1, y[b] = 0;
                        else if(y[x[i]]==y[b])
                            y[x[i]] = 0, y[b] = 0;
                        else
                            y[b] = y[b] - y[x[i]] - 1, y[x[i]] = 0;
                    }
                    else
                        y[x[i]]--;
                    ans++;
                }
            }
            cout << ans << endl;
        }
    }

C1题目链接 这里

题解:这个题说的是,让我们找3个数,使这三个数相加等于n,且这三个数的最小公倍数小于等于n/2. 既然要小于等于n/2,我们可以使这个数除以2,得到m,这样可以得到两个数,如果n-2m!=0,那么剩下的数就是第三个数,如果n-2m==0,那么我们就要考虑把这两个数分一点给第三个数,如果m是偶数,那么我们使m/2即可得到第三个数,如果m是奇数,那么除以二是不可以的,我们让每个数给第三个数1,这样第三个数为2,一定是m-1的因数,这时lcm也不会超过n/2.

    #include<bits/stdc++.h>
    #define ll long long
    #define pr pair<ll,ll>
    #define ios ios::sync_with_stdio(false)
    #define CRL(a) memset(a,0,sizeof a)
     
    using namespace std;
     
    const int maxn = 5e6 + 5;
    pr x[maxn];
    int a[maxn], b[maxn];
    int main()
    {
        int t;
        cin >> t;
        while(t--)
        {
            int n, m;
            cin >> n >> m;
            int b = n / 2;
            int d = b;
            int c = n - b * 2;
            if(c==0)
            {
                if(b&1)
                {
                    b--, d--;
                    c = 2;
                }
                else
                    d /= 2, c = d;
            }
            cout << b << " " << d << " " << c << endl;
        }
        return 0;
    }

C2题目链接这里
题解:这个题和上个题不一样的是这次不是三个数了,而是任意数,但1对lcm是没有影响的,我们可以让第三个数后面的数全部为1,转化为上一题,求解。

    #include<bits/stdc++.h>
    #define ll long long
    #define pr pair<ll,ll>
    #define ios ios::sync_with_stdio(false)
    #define CRL(a) memset(a,0,sizeof a)
     
    using namespace std;
     
    const int maxn = 5e6 + 5;
    pr x[maxn];
    int a[maxn], b[maxn];
    int main()
    {
        int t;
        cin >> t;
        while(t--)
        {
            int n, m;
            cin >> n >> m;
            n -= m - 3;
            int b = n / 2;
            int d = b;
            int c = n - b * 2 ;
            if(c==0)
            {
                if(b&1)
                {
                    b--, d--;
                    c = 2;
                }
                else
                    d /= 2, c = d;
            }
            cout << b << " " << d << " " << c << " ";
            for (int i = 1; i <= m - 3;i++)
                cout << 1 << " ";
            cout << endl;
        }
        return 0;
    }

E1题目链接 这里
题解:这个题让我们求子数组,每个数组当中的数相乘都不是完全平方数,让我们求这样的有几个。
由质因数分解我们可以知道任意一个大于1的正整数都能唯一分解为有限个质数的乘积。那么我们可以知道如果一个数和另外一个数相乘想成为平方数,他们相乘的数分解为质数的乘积,这些质数的次方都是2的倍数。我们可以让分解的质数的次方对2取余,然后让取余为1的质数相乘,可以得到这样的话必须两个数相等才能为完全平方数。然后我们就可以得到答案。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e7 + 5;
    int pr[maxn], st[maxn];
    int cnt = 0;
    void prime(int n)
    {
        for (int i = 2; i <= n;i++)
        {
            if(st[i]==0) 
            {
                st[i] = i;
                pr[++cnt] = i;
            }
            for (int j = 1; j <= cnt;j++)
            {
                if(pr[j]>st[i]||pr[j]>n/i)
                    break;
                st[i * pr[j]] = pr[j];
            }
        }
    }
    int main()
    {
        int t;
        cin >> t;
        prime(10000001);
        while(t--)
        {
            int n, m;
            cin >> n >> m;
            vector<int> q(n, 1);
            for (int i = 0; i < n;i++)
            {
                int a;
                cin >> a;
                int last = 0, ans = 0;
                while(a>1)
                {
                    int p = st[a];
                    if (p == last)
                    {
                        ans++;
                    }
                    else 
                    {
                        if(ans%2)
                            q[i] *= last;
                        last = p;
                        ans = 1;
                    }
                    a /= p;
                }
                if(ans%2)
                    q[i] *= last;
            }
            int l = 0, ans = 1;
            map<int, int> ma;
            for (int i = 0; i < n;i++)
            {
                if(ma.find(q[i])!=ma.end()&&ma[q[i]]>=l)
                {
                    ans++;
                    l = i;
                }
                ma[q[i]] = i;
            }
            cout << ans << endl;
        }
    }
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值