第十届“新华三杯”k题“我来组成头部”解题思路

题目:

样例:

        这次比赛是作为我们新生团体赛的训练题目,我刚开始看到这题还一脸懵圈,疑问很多。例如为什么每一组数据的答案明明有很多却只输出这一个?还有一个方程有五个参数,如果答案是唯一的那么规律到底要怎么找?也是怪我见少识浅了确实是第一次接触到这种构造题目,我刚开始毫无头绪,准备先暴力一下看看有什么规律,当我花了些时间敲出来五重循环的暴力后,嗯,没有发现规律。

        在我们比赛的后面时间所剩不多了,最后决定搏一搏想这样构造:

思路一:

        我们想先找对结果影响最大的数,先确定下来它们,我们把目光放在了c和e,因为当数据大的时候肯定a和b很难控制,所以干脆就让他为0,即b>a,然后只需要让c=sqrt(n),e=c+1这样做那d自然而然就是d=n-c*e,但是这样写问题就很多,当sqrt(n)正好为一个整数的时候,也就是n被开根后正好是一个整数,那么简单的计算就可以得知此时d=c,与题意不符。当然这是可以避免的,例如当sqrt(n)为一个整数的时候我们可以让c++,e++。那么这样就可以解决上面的问题,但是其他的问题又接踵而至,总之就是麻烦很多,最后能不能写出来我不知道,可能能写出来,但是太过麻烦。

正解:

        就是对简单的运算先下手,这样后面的计算只会更简单,并且舍弃用a,b,c,d,e来表示a,b,c,d,e而是直接用n与常数来直接构造a,b,c,d,e,这样做的好处就是a,b,c,d,e有没有重复的一眼便知,近乎完美的解决了思路一的各种疑难杂症。接下来就是大量的尝试,用开头所说的先对简单的运算下手,那么便是d,因为它既不在括号里,也没有其他运算。将d移到等号右面:(a/b+c)*e=n+d   我们再向左面乘积的形式靠拢,那么令d=n是不是就变成了(a/b+c)*e=n*2  是不是越来越像了,我们在让e=2,就变成了a/b+c=n  这个时候想,n这个值已经被d给占用了,所以令c=n-1,a/b=1不就行了,确实是行了,但是a和b没表示出来,我们再找其他没被用过的值,让a=n-2,b=n-3这样就完美符合了,但是当n=5时有重复,也只有n=5时有重复,所有我们特判一下就可以了。

        (补充一下)为什么让d=n而不是其他数呢?因为我们想要凑出左面的形式,也就是乘积形式,但是题目明确说了不能大于n不能等于0,且是整数,所以最后能选择的只有d=n。也就有了下面不难理解的思路。

有了上述思路便可以很简单完成以下操作:

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main(){
    int q;
    cin>>q;
    while(q--){
        int n;
        cin>>n;
        if(n==5)cout<<"4 5 2 1 3"<<'\n';
        else{
            cout<<n-2<<' '<<n-3<<' '<<n-1<<' '<<n<<' '<<2<<'\n';
        }
    }
    
    
    return 0;
}

总结: 

         思路一之所以没成功的原因就是用a,b,c,d,e来表示彼此了,所以对重复的数很难判断,尽管我们最后用了二分,map也没能补救,还有就是要先从简单的下手。这篇主要来警示自己与遇到同样构造问题的朋友。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值