zoukankan      html  css  js  c++  java
  • LuoguP1286 两数之和

    题面概括

    将n个数两两相加得到n*(n-1)/2个和,给出这些和,求所有原数方案
    n<=500
    LuoguP1286

    题解

    此题原题是 n<10, 没啥可做的
    先将 (n*(n-1)/2) 个数排序
    设b[i]表示给定的数中第i小的, a[i]为原数第i小的
    显然有: b[1]=a[1]+a[2],b[2]=a[1]+a[3]
    那么 i>=3 时呢?
    则是不一定的
    考虑为什么不一定: 我们无法判断 (b[3] = a[1]+a[4]) 还是 (b[4] = a[2]+a[3])
    那b[3]还可不可能等于其他的组合呢?
    显然是不能的(不解释),
    b[3]如此,b[4]呢? b[5]呢?

    不难发现若 b[j]=a[p]+a[q] 当j确定后 (q_max=j+1),此时 p=1
    所以我们可以通过枚举p,q(p!=1)来将b[j]删掉,剩下的数就一定是 a[1]+a[j+1]=b[j]
    枚举a[1]则可以轻松推出剩下的数

    删除操作用 multiset 实现,格外好写

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define int ll
    #define re register
    #define ll long long
    #define get getchar()
    #define in inline
    in int read()
    {
    	int t=0; char ch=get;
    	while(ch<'0' || ch>'9') ch=get;
    	while(ch<='9' && ch>='0') t=t*10+ch-'0', ch=get;
    	return t;
    }
    const int _=601;
    multiset<int > s;
    int n,b[_<<10],a[_],f[_],N,st,ans[_][_],tot;
    in void solve(int k)
    {
    	a[1]=(b[2]+b[1]-b[k])/2;
    	a[2]=b[1]-a[1];
    	a[3]=b[k]-a[2];
    }
    void calc(int qwe)
    {
    	for(re int i=4;i<=n;i++)
    	{
    		multiset<int> :: iterator it=s.begin();
    		a[i]=*it-a[1];
    		s.erase(it);
    		if(a[i]<a[i-1]) return;
    		for(re int j=2;j<i;j++)
    		{
    			it=s.find(a[i]+a[j]);
    			if(*it!=a[i]+a[j]) return;
    			s.erase(it);
    		}
    	}
    	tot++;
    	for(re int i=1;i<=n;i++) { ans[tot][i]=a[i]; }
    	f[qwe]=1;
    }
    signed main()
    {
    	while(cin>>n)
    	{
    		memset(f,0,sizeof(f));
    		memset(ans,0,sizeof(ans));
    		s.clear();
    		tot=0;
    		N=(n-1)*n/2;
    		for(re int i=1;i<=N;i++) b[i]=read();
    		sort(b+1,b+N+1);
    		for(re int i=3;i<=N && b[2]+b[1]>=b[i];i++)
    		{
    			if((b[2]+b[1]-b[i])&1)  continue;
    			if(b[i]==b[i-1]&&f[i-1]) {f[i]=1;continue;}
    			solve(i);
    			if(a[3]<a[2] || a[2]<a[1]) continue;
    			s.clear();
    			for(re int j=3;j<=N;j++)
    				if(j!=i) s.insert(b[j]);
    			calc(i);
    		}
    		if(tot==0) {
    			cout<<"Impossible"<<endl;
    			continue;
    		}
    		for(re int i=tot;i>=1;i--){
    			for(re int j=1;j<=n;j++) cout<<ans[i][j]<<' ';
    			cout<<endl;
    		}
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    触摸屏与usb鼠标同时支持
    QT国际化(lupdate/linguits/lrelease)生成.ts,转换成.qm方法
    Qt5 使用lambda
    c++中lambda表达式的用法
    异或运算的作用
    函数指针和指针函数用法和区别
    前端html页面学习---html部分
    二:maven构建module
    一:使用maven构建项目
    maven项目发布到tomcat后没有lib目录解决方案
  • 原文地址:https://www.cnblogs.com/yzhx/p/13830524.html
Copyright © 2011-2022 走看看