题目大意:
从1-1000000中选取n个数,组成一个集合X,然后
在剩余的数中寻找到m个数,组成集合Y,使其满足:
(s=1000000)
解题思路:
一般这种在没有思路的时候,我们最先想到的是模拟,然后在模拟的过程中进行优化。
先列出我模拟的代码:
#include <cstdio>
#include <algorithm>
#define INF 1000000
const int maxn=1000000+10;
using namespace std;
bool a[maxn];
int n;
bool xz(long long m,long long sum,long long q){ //选取m代表前m-1个数已经选取过了,sum代 表还剩下的和 q代表已经选取的数个数;
if (q>INF-n) return false; //如果q+n>INF 不满足情况 退出
for (long long i=m;i<=1000000;i++){
if (a[i]==false&&sum+i-INF==0) {
printf("%I64d\n",q);
printf("%I64d ",i);
return true;
}
if (!a[i]&&sum+i-INF>0){
a[i]=true;
if (xz(i+1,sum+i-INF,q+1)){
printf("%I64d ",i);
return true;
}
a[i]=false;
}
if (!a[i]&&sum+i-INF<0) { //使用二分法加快求解
long long L,R;
L=i;R=INF;
while (L<R){
long long mid=(L+R)/2;
if (sum+mid-INF<0) L=mid+1;
else R=mid;
}
i=L-1;
}
}
return false;
}
int main (){
long long sum;
while(scanf("%d",&n)!=EOF){
sum=0;
for (int i=1;i<=n;i++) a[i]=false;
for (int i=0;i<n;i++){
long long b;
scanf("%I64d",&b);
a[b]=true;
sum+=b-1;
}
xz(1,sum,1);
printf("\n");
}
return 0;
}
但是不过如何优化,使用模拟的方法这题我都没过去(如果你有模拟过的,请告诉我);
但是仔细分析后,发现这题有规律。
就以s=8 为例
1 2 3 4 5 6 7 8
X 0 1 2 3 4 5 6 7
Y 7 6 5 4 3 2 1 0
上图所示的是全集中的数在X与在Y中的值为多少;
聪明的你应该想到方法了吧!
对于一个在X中的数i(i<=500000)如果(1000001-i)没有在X中,我们就选择它。如果在了,我们就选择一组
(i)与(1000001-i)都没有在X中的数。
我的代码:
#include <cstdio>
#include <algorithm>
#define INF 1000000
using namespace std;
const int maxn = 1000001;
bool a[maxn];
int b[maxn/2];
int main (){
int n,m=0;
while (scanf("%d",&n)!=EOF){
for (int i=1;i<=n;i++) a[i]=false;
for (int i=0;i<n;i++){
int b;
scanf("%d",&b);
a[b]=true;
}
int ans=0,q=0,m=0;
for (int i=1;i<=INF/2;i++){
if (a[i]&&a[INF+1-i]) q++;
if (q&&!a[i]&&!a[INF+1-i]) {
a[i]=a[INF+1-i]=true;
b[m++]=i;
b[m++]=INF+1-i;
q--;
n-=2;
ans+=2;
}
if (a[i]&&!a[INF+1-i]) {n--;a[INF+1-i]=true;b[m++]=INF+1-i;ans++;}
if (!a[i]&&a[INF+1-i]) {n--;a[i]=true;b[m++]=i;ans++;}
if (!n) break;
}
if (n){
for (int i=1;i<=INF/2;i++){
if (q&&!a[i]&&!a[INF+1-i]) {
a[i]=a[INF+1-i]=true;
b[m++]=i;
b[m++]=INF+1-i;
q--;
n-=2;
ans+=2;
}
if (!q) break;
}
}
printf("%d\n",ans);
for (int i=0;i<m;i++)
printf("%d ",b[i]);
printf("\n");
}
return 0;
}