2020/7/30—组队赛总结+补题

博客总结了团队在编程比赛中的合作经验,指出了沟通不足的问题,并分享了补题过程。文章详细分析了一道关于构造特定集合的数学题,讨论了解题思路和优化方法,还探讨了一道字符串处理题目的解法,强调了学习他人优秀编程技巧的重要性。
摘要由CSDN通过智能技术生成

首先总结:
1.总体配合非常良好,感觉有1+1+1>3的效果.
2.在时间分配上,我觉得一开始分开各做各的是不错的,但是把签到题和简单题做完后,我 们比较缺少题目上的交流和沟通,以后会多讨论.
3.遇到一些问题还是急躁,不知所措,因为多与队友交流.

补题:
在这里插入图片描述
在这里插入图片描述
这个题我们AC六题后,我们三个人都在搞这个题,但是一方面英语题面,对题目理解有些问题,另一方面,在最后我们思路已经很接近了,但是实现又成了问题,代码写的有问题,时间也不够了,遗憾吧.

题目大意:
给出一个数字n,让我们构造出不超过100个数的一个集合,使得其集合所有数的加和为n。
要求集合中的数字任取两个数字的Gcd都是1,而且需要保证每个数都能写成 2 x ∗ 3 y 2^x*3^y 2x3y的形式。

题目代码:
本代码转载于此博客,我已经复现,没有需要改的地方.
另外,思路还是这篇博客讲得好.也解释了为什么这样做可以保证gcd=1.

题目分析:
我们先整出一个 n = 2 x ∗ 3 y ∗ w n=2^x*3^y*w n=2x3yw,这个w即不能和2整除也不能和3整除,然后我们找3的z次方,这个数比w小,为了保证效率,我们找符合条件的数里最大的那个,然后w= 2 0 ∗ 3 z ∗ s 2^0*3^z*s 203zs,这时候s就可以递归了,就是下一个循环里的n,然后我们再把 2 x ∗ 3 y 与 3 z 合 并 成 2 x ∗ 3 z ∗ 3 y ) 2^x*3^y与3^z合并成2^x*3^z*3^y) 2x3y3z2x3z3y)

#include<bits/stdc++.h>
using namespace std;
#define maxn 1005

long long  a[maxn],cnt,ans[maxn];
void judge(long long x,long long temp)
{
    long long y;
    while(x%3==0)
    {
        x/=3;
        temp*=3;
    }
    while(x%2==0)
    {
        x/=2;
        temp*=2;
    }
    if(x==1)
        ans[cnt++]=temp;
    else
    {
        y=3;
        while(y*3<x)
        {
            y*=3;
        }
        ans[cnt++]=temp*y;;
        judge(x-y,temp);
    }
}
int main()
{
    //freopen("distribution.in", "r", stdin);
    //freopen("distribution.out", "w", stdout);
    int t;
    scanf("%d",&t);
    for(int i=0; i<t; i++)
        cin>>a[i];
    for(int i=0; i<t; i++)
    {
        cnt=0;
        judge(a[i],1);
        cout<<cnt<<endl;
        for(int j=0; j<cnt; j++)
        {
            if(j==0)
                cout<<ans[j];
            else
                cout<<" "<<ans[j];
        }
        cout<<endl;
    }
    return 0;
}

在这里插入图片描述
在这里插入图片描述

这个题不是我写的,但是我看了,我说实话,虽然是简单题,但我真不一定能做出来.

解题思路:
根据长宽比例可以算出三种情况,如果长比宽大三倍以上,那么正方形边长就是宽;如果长在宽的1.5倍到3倍之间,那么正方形边长就是长/3;如果长在宽的1到1.5倍之间,那么就看做是在长方形内部画一个田字,正方形边长就是宽/2。

题目代码:

#include <bits/stdc++.h>
using namespace std;

int main()
{
    //freopen("alex.in","r",stdin);
    //freopen("alex.out","w",stdout);
    double h,w;
    while(~scanf("%lf %lf",&h,&w))
    {
        double ans;
        if(w>h) swap(w,h); 
        if(h>3*w)
        ans=w;
        else if(h>3.0*w/2.0)
        ans=h/3.0;
        else
        ans=w/2.0;
        printf("%.6f\n",ans);
    }
    return 0;
}

思路和代码出自这个博客,说实话我只是学会了这个思路或者方法,至于为什么这样做,这个内在原理,我还是不懂,也搜不到,有点郁闷.

在这里插入图片描述
在这里插入图片描述
这个题的代码:这个博客的代码很好.
他的题意分析:
让数组a和数组b的长度相乘然后减去a中a和b相同的字母的个数.
我觉得其中有几种情况要说明:
1.比如字符串A有6个E,字符串B只有1个E,不讨论其他字符,减去相同的个数为6个呢,就是字符串B中的E和字符串A中的六个E都算是重复呢.
2.再比如字符串A有2个E,字符串B也有3个E,不讨论其他字符,每在字符串B遇到一次E,就算两次(在字符串A有2个E),统共6次.
不会的题我不喜欢自己写代码,喜欢看看别人的再改进,原因就在于学习别人的好写法.
比如这个题:

#include<bits/stdc++.h>
using namespace std;

long long aa, bb, res, i;
char a[100005],b[100005];
int sum[200];
int main()
{
    //freopen("concatenation.in","r",stdin);
    //freopen("concatenation.out","w",stdout);
    scanf("%s",a);
    scanf("%s",b);
    aa = strlen(a);
    bb = strlen(b);
    res = aa * bb;
    for(i = 1; i < aa ; i++) //注意合体字符串的头和尾不用管重复的问题,这是很重要的点!所以才从1开始遍历.
        ++sum[a[i]];
    for(i = 0 ; i < bb - 1; i++)//同上,最后一个不用遍历.
        res -= sum[b[i]];
    printf("%lld\n",res);
    return 0;
}

这个代码我就只把一句memset让sum全变0的代码删了,因为不是多次循环,而且sum是全局变量自动为0.但是他这种写法就很巧妙,找两字符串相同的字符,如果是我就挨着找了,然后再用一个数组存起来,即使是求其数量,我也会遍历挨着数,但是他就是让在A字符串中出现的字母在sum数组里计数,在字符串B中出现这个字母,就减去在字符串A中出现的次数,我觉得很巧妙;要学习和记录一下,以后有机会可以用.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值