• 第十五次开心场


    A - AAA

    CodeForces - 1047A

    A

    题意:给定一个数,分解为三个不为3的倍数且 a + b + c = n 的数

    思路:简单贪心,根据情况输出 1,1,n -21,2,n-3

    int main() {
        // freopen("in.txt","r",stdin);
        ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
        // for (cin >> _; _; _--) solve();
        cin >> n;
        if (n % 3 == 0 || n % 3 == 1)
            cout << 1 << " " << 1 << " " << n - 2 << endl;
        else 
            cout << 1 << " " << 2 << " " << n - 3 << endl;
    }
    

    B - BBB

    CodeForces - 1047B

    B

    emm,很简单

    int n,a,b;
    int main() {
        cin >> n;
        while (n--) {
            cin >> x >> y;
            b = max(b, y + x);
        }
        cout << b << endl;
    }
    

    C - CCC

    CodeForces - 1047C

    C题开始的自闭路途

    C

    题意

    给出n个数,记它们的gcd为g,现在询问最少去掉多少个数可以使剩下的数的gcd大于g。

    思路:

    想了半天,最后才知道可以暴力

    先求出所有数的gcd记作gg,然后把原数组中所有的数除去这个因数gg。然后再把除去后的数组中所有的数分解质因数,用一个cnt[ ]来记录一个因数在这个除去gg的数组中共出现了几次。现在我们的目的是想让gcd增大,那么其实就是需要删掉那些在除去gg后数组中没有相同因数的数字。暴力竟然没有超时???

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 3e5 + 5, M = 1.5e7 + 5;
    int n, g, ans, a[N], cc[M], np[M];
    
    int main() {
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) scanf("%d", a + i), g = __gcd(a[i], g);
        for (int i = 1; i <= n; ++i) ++cc[a[i] / g];
        for (int i = 2; i < M; ++i) {
            if (!np[i]) {
                int res = 0;
                for (int j = i; j < M; j += i) np[j] = 1, res += cc[j];
                ans = max(ans, res);
            }
        }
        printf("%d
    ", ans ? n - ans : -1);
    }
    

    D - DDD

    CodeForces - 1029C

    D

    题意:

    给你一个n个区间[l,r],问当你删掉某1个区间后,剩下的n-1个区间所能够相交的长度的最大值。

    思路:

    首先,我们首先考虑将所有的左括号和所有的右括号从小到大排序,那么不难发现,倘若我们需要求多个区间的相交的长度,那么我们只能选取左括号中序号最大的和右括号中最小的,他们相减即为最大长度(若为负数则为0)。

    而题目中要求我们删掉某个区间,我们于是我们就可以考虑枚举被删的区间。我们可以用multiset分别存储左右括号的坐标,在枚举的过程中先删除第i个区间,统计答案之后再加上第i个区间。不断遍历更新最大值即可。

    #include <bits/stdc++.h>
    #define maxn 300005
    using namespace std;
    multiset<int>l,r;
    struct Seg{
        int l,r;
    }q[maxn];
    int main()
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++){
            scanf("%d%d",&q[i].l,&q[i].r);
            l.insert(q[i].l);//用multiset存左右括号
            r.insert(q[i].r);
        }
        int res=0;
        for(int i=1;i<=n;i++){
            l.erase(l.find(q[i].l));//删除第i个区间
            r.erase(r.find(q[i].r));
            res=max(res,*r.begin()-*--l.end());//答案是右区间的最小值和左区间的最大值
            l.insert(q[i].l);
            r.insert(q[i].r);
        }
        cout<<res<<endl;
    }
    

    E - EEE

    CodeForces - 1029D

    E

    题意:给你n个数,一个k,每两个数连接起来mod k==0的组合有多少个.

    对于题目给的n规模暴力是不可能了,只能先进行预处理,然后判断是否存在即可

    // Author : RioTian
    // Time : 20/10/29
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 2e5 + 100;
    ll n, a[N], k, ans, t;
    map<ll, ll> mp[20];
    int getlen(ll x) {
        int cnt = 0;
        for (; x; x /= 10) cnt++;
        return cnt;
    }
    int main() {
        // freopen("in.txt", "r", stdin);
        ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
        cin >> n >> k;
        for (int i = 1; i <= n; i++) {
            cin >> a[i], t = a[i];
            for (int j = 1; j <= 10; j++) {
                t = t * 10 % k;
                mp[j][t]++;
            }
        }
        for (int i = 1; i <= n; i++) {
            int len = getlen(a[i]);
            ans += mp[len][(k - a[i] % k) % k], t = 1;
            for (int i = 1; i <= len; i++) t = t * 10 % k;
            if ((a[i] * t % k + a[i] % k) % k == 0) ans--;
        }
        cout << ans << endl;
    }
    

    F1

    CodeForces - 1029A

    F1

    F2

    https://codeforces.com/contest/1029/problem/E

    F2

    虽然知道是树上问题,但一直没想到用搜索就能解决了(傻傻的推DP状态转移方程去了)

    #include<bits/stdc++.h>
    #define N 200000+10
    using namespace std;
    vector<int>g[N];
    int ans,n,x,y;
    int dfs(int u,int p=0)
    {
    	int x=2;
    	for(int i=0;i<g[u].size();i++)
    	{
    		int v=g[u][i];
    		if(v!=p)
    		x=min(x,dfs(v,u));
    	}
    	if(u!=1&&p!=1&&x==0)
    	ans++;
    	
    	return (x+1)%3;
    }
    int main()
    {
    	cin>>n;
    	for(int i=1;i<n;i++)
    	{
    		cin>>x>>y;
    		g[x].push_back(y);
    		g[y].push_back(x);
    	}
    	dfs(1,0);
    	cout<<ans;
    	return 0;
    }
    

    The desire of his soul is the prophecy of his fate
    你灵魂的欲望,是你命运的先知。

  • 相关阅读:
    第十三周总结
    第十二周作业
    第十一周课程总结
    第十周课程总结
    第九周课程总结&实验报告(七)
    第八周课程总结&实验报告(六)
    第七周课程总结&实验报告(五)
    第六周&java实验报告四
    课程总结
    第二周课程总结
  • 原文地址:https://www.cnblogs.com/RioTian/p/13902496.html
Copyright © 2020-2023  润新知