hdoj 1563 Find your present!&&2095 Find your present(2) 异或运算



http://acm.hdu.edu.cn/showproblem.php?pid=1563

Find your present!

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2747    Accepted Submission(s): 1819


Problem Description
In the new year party, everybody will get a "special present".Now it's your turn to get your special present, a lot of presents now putting on the desk, and only one of them will be yours.Each present has a card number on it, and your present's card number will be the one that different from all the others.For example, there are 5 present, and their card numbers are 1, 2, 3, 2, 1.so your present will be the one with the card number of 3, because 3 is the number that different from all the others.
 


Input
The input file will consist of several cases.
Each case will be presented by an integer n (1<=n<=200, and n is odd) at first. Following that, n positive integers will be given in a line. These numbers indicate the card numbers of the presents.n = 0 ends the input.
 


Output
For each case, output an integer in a line, which is the card number of your present.
 


Sample Input
  
  
5 1 1 3 2 2 3 1 2 1 0
 


Sample Output
  
  
3 2



#include<stdio.h>
#include<string.h>
struct NUM
{
    int N;
    int num;
}num[400];
int main()
{
    int M,i,j,k,a[400];
    while(scanf("%d",&M)&&M!=0)
    {
        memset(a,0,sizeof(a));
        for(i=0;i<M;i++)
        scanf("%d",&a[i]);
        for(i=0;i<400;i++)
            num[i].num=0;

        for(i=0,j=0;i<M;i++)
        {
            if(a[i]!=-1)
            num[j].N=a[i];
            else continue;

            for(k=0;k<M;k++)
            if(num[j].N==a[k])
            {
                num[j].num+=1;
                a[k]=-1;
            }

            j+=1;
        }
        for(i=0;i<j;i++)
        if(num[i].num==1)
        break;

        printf("%d\n",num[i].N);
    }
    return 0;
}

这道题就是让找只出现一次的那个号码,可以用数组,把号码存到数组中,然后扫描数组,把出现的号码和号码的个数放到结构体中,结构体是号码和号码出现的次数,然后输出号码出现次数是1对应的那个号码。


http://acm.hdu.edu.cn/showproblem.php?pid=2095

find your present (2)

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/1024 K (Java/Others)
Total Submission(s): 15707    Accepted Submission(s): 5992


Problem Description
In the new year party, everybody will get a "special present".Now it's your turn to get your special present, a lot of presents now putting on the desk, and only one of them will be yours.Each present has a card number on it, and your present's card number will be the one that different from all the others, and you can assume that only one number appear odd times.For example, there are 5 present, and their card numbers are 1, 2, 3, 2, 1.so your present will be the one with the card number of 3, because 3 is the number that different from all the others.
 


Input
The input file will consist of several cases.
Each case will be presented by an integer n (1<=n<1000000, and n is odd) at first. Following that, n positive integers will be given in a line, all integers will smaller than 2^31. These numbers indicate the card numbers of the presents.n = 0 ends the input.
 


Output
For each case, output an integer in a line, which is the card number of your present.
 


Sample Input
  
  
5 1 1 3 2 2 3 1 2 1 0
 


Sample Output
  
  
3 2
Hint
Hint
use scanf to avoid Time Limit Exceeded

#include<stdio.h>
#include<string.h>
int main()
{
	int N,n,i,sum;
	while(scanf("%d",&N)&&N!=0)
	{

		for(i=0,sum=0;i<N;i++)
		{
		   scanf("%d",&n);
		   sum^=n;
	    }
		printf("%d\n",sum);
	}
	return 0;
}

这道题是上道题的拓展,这道题的范围是1<=n<1000000,每个数不超过2^31,这说明测试数据会很大,我用上一题的做法提交,结果超内存。看其他人做才知道要用异或运输,异或运算是计算机中特有的,先把两个数转化成二进制码,然后异取1,同取0,如3^2=11^10=01,所以两个相同的数异或是0,2^2=10^10=00。因为这题输入的号码是偶数个,你的号码是出现一次的,剩余就是偶数个号码,而且其余的号码出现的次数也是偶数次(隐含条件,如果不是的话,就不能用异或运算),所以对号码依次进行异或运算,最后的号码就是出现1次的号码,即你的号码。

注意:

1)第一题用普通法(11855420)和异或法(11858741)如下图,可见在数据少的时候异或运算和普通运算一样。

第二题用普通法和异或法如下图,由此就可看出异或运输的优势,用普通法要用数组存,会超内存,而用异或运算不用储存。这也说明异或用算不会节省时间。

2)从这两道题还可以知道,这两道题还有一个隐含条件,即除了你的号码出现次数是1,其余号码出现次数都是偶数次。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值