• NowCoder Wannafly 27E 黄魔* 构造


    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-Wannafly27E.html

    题目传送门 - NowCoder Wannafly 27E

    题意

      给出 n, k,求一个长度为 n 的数组 a, 满足有恰好 k 对数对 (i, j) (1 <= i < j <= n) 满足 ai + aj 为完全平方数。如果不存在,输出 -1。

    题解

      首先考虑最大能构造多少:

      容易发现,全部填 2 就是 n(n-1)/2 最大了。然后猜一猜小于等于这个的都是有解的。

      首先,找到满足 m(m-1)/2<=k 的最大 m , 则 k = 1+2+ … + m + x

      我们考虑构造这 m+1 个数来达到目的,假装其他的数不影响结果,设为 d 。

      于是可以想到一种构造方案:

      找到正整数 a,b,c,d ,满足:

        a+b,a+a,b+b,b+c 是完全平方数

        a+c,a+d,b+d,c+d,d+d,c+c 不是完全平方数。

      那么,我们考虑分 x = 0 和 x>0 讨论:

      如果 x = 0 ,那么直接放 m 个 a 然后其他的放 d 就好了。

      如果 x > 0 ,那么放 m-x 个 a,x 个 b,放一个 c ,剩下的放 d 即可。

      手造出这样的 abcd 比较麻烦,但是这样的 abcd 在 10w 范围内显然是很容易找的,直接写个代码暴搜即可。

      由于 我太懒了,直接用了 珂爷 的: a=98,b=2,c=7 。我 d 随便取了个 1 。

      话说 珂爷 太巨了,E 题一血虐场 Orz 。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N=100005;
    LL read(){
    	LL x=0;
    	char ch=getchar();
    	while (!isdigit(ch))
    		ch=getchar();
    	while (isdigit(ch))
    		x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    	return x;
    }
    LL n,k;
    int a=98,b=2,c=7,d=1;
    vector <int> v;
    int main(){
    	n=read(),k=read();
    	if (n*(n-1)/2<k)
    		return puts("-1"),0;
    	if (!k){
    		for (int i=1;i<=n;i++)
    			printf("1 ");
    		return 0;
    	}
    	v.clear();
    	while ((n-1)*(n-2)/2>=k){
    		v.push_back(d);
    		n--;
    	}
    	if (n*(n-1)/2==k)
    		for (int i=1;i<=n;i++)
    			v.push_back(a);
    	else {
    		v.push_back(c);
    		LL rem=k-(n-1)*(n-2)/2;
    		for (int i=1;i<=rem;i++)
    			v.push_back(b);
    		for (int i=n-1-rem;i>=1;i--)
    			v.push_back(a);
    	}
    	for (auto i : v)
    		printf("%d ",i);
    	return 0;
    }
    

      

  • 相关阅读:
    2月3日
    照片测试
    家属签证计时
    我来了
    090204 阴天
    重要提醒to 小爱
    小毛小毛
    C++Primer学习日程
    资料库字段存储文件记录的方式
    本日有点忙
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/NowCoder-Wannafly27E.html
Copyright © 2020-2023  润新知