2653: 不同的数
Result | TIME Limit | MEMORY Limit | Run Times | AC Times | JUDGE |
---|---|---|---|---|---|
3s | 65536K | 409 | 82 | Standard |
原来有n对数字,每对两个数字都相同。现在其中某对数字中的一个发生了变化。并且所有数字被打乱了顺序。求这一对数字变化后是多少。要求先输出小的。再输出大的。
Input
多组输入,每组如下: 第一行一个数字n, n <= 1000000 以下2n行,每行一个数字,打乱顺序后的所有数字。 n=0表示输入结束。
Output
每组一行。两个数字。表示发生变化后的一组。
Sample Input
3
1
2
3
2
2
3
0
Sample Output
1 2
Hint
这是一个内存受限的题目,意味着你不可能开辟一个数组,把所有的数据存进去。请思考更好的算法。
/*这个题目是一个位运算的一个应用。对于相等的两个数他们的异或值必然是0;
如果两个数不相等必定在2进制表示的数中某个位置是不同的并且一个是0,一个
是1,因此申请两个数组分别表示储存在这个位置上是0,是1的数。并且用一个temp
来储存两个不相等数的异或值。当遇到temp的某个位是1的时候两个数组分别
表示的数就是那两个不相等的数(每个是1的位都是)*/
#include<iostream>
#include<string.h>
using namespace std;
int num1[33];
int num2[33];
int main()
{
int n;
while(cin>>n,n)
{
memset(num1,0,sizeof(num1));//对每个位代表的数初始化为0
memset(num2,0,sizeof(num2));
int temp=0;
for(int i=1;i<=n*2;i++)
{
int m;
cin>>m;
for(int j=0;j<32;j++)
{
if(m&(1<<j))
num1[j]=num1[j]^m;//当j位是1的时候将m付给num1
else
num2[j]=num2[j]^m;//当j位是0的时候将m付给num2
}
temp=temp^m;//记录不相等的两个数的异或值
}
for(int i=0;i<32;i++)
{
if(temp&(1<<i))
{
if(num1[i]<num2[i])
cout<<num1[i]<<" "<<num2[i]<<endl;
else
cout<<num2[i]<<" "<<num1[i]<<endl;
break;
}
}
}
return 0;
}
或者是更简单的一种方式直接用new来申请那个2n数组。因为new是在堆区申请空间
因此内存不会超,但是这种方法肯定不是出题人的意图。。
#include<stdio.h>
#include<algorithm>
using namespace std;
int *a=new int[1000000*2];
int main()
{
int n;
while(scanf("%d",&n),n)
{
for(int i=0;i<2*n;i++)
{
scanf("%d",&a[i]);
}
sort(a,a+2*n);
for(int i=0;i<2*n;i++)
{
if(i%2==0)
{
if(a[i]!=a[i+1])
{
printf("%d %d\n",a[i],a[i+1]);
break;
}
}
}
}
return 0;
}