P1469 找筷子

摘要:有n根(n为奇数)长短不一的筷子,里面可以凑成(n-1)/2双筷子,只剩下一根不能凑对,问那根不能凑对的筷子有多长。

乍听起来好像不难,桶是一个好东西,可是一看数据:对于100%的数据,N<=10000001,筷子长度不大于 10^9。

桶直接就淘汰掉了。

但是其实我第一次A用的却是桶,直接上代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,t,a[10000010];
int main(){
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&t);
        a[t]++;//桶计算
        if(a[t]==2){
            a[t]-=2;//如果凑成一对了就把他减去
        }
    }
    for(long long i=0;i<=1000001;i++){
        if(a[i]>0){
            printf("%d\n",i);//如果在遍历桶的时候找到了那根落单的筷子就直接输出。
                        break;
        }
    }
    return 0;
}

靠的是一股巧劲儿。

直到我做完这题不久后,我得知了一个神奇的东西:^异或符号

0^0=0,0^1=1 0异或任何数=任何数

1^0=1,1^1=0 1异或任何数-任何数取反

任何数异或自己=把自己置0

异或运算符的特点是:数a偶数次异或同一个数b(例如:a=a^b^b)仍然为原值a。

所以我们只要在输入的时候一直异或,就可以得到落单的那跟筷子的长度(我刚知道的时候像发现了新大陆一样)。

代码如下:

#include<iostream>
#include<cstdio>
using namespace std;
int n,m,ans=0;
int main(){
    scanf("%d",&n);//输入一共有几根筷子
    for(int i=0;i<n;i++){
    scanf("%d",&m);//输入每根筷子的长度
        ans^=m;//异或大法好,只要一直这样最后得出来的结果肯定是落单的那根筷子的长度。
    }
    cout<<ans<<endl;
    return 0;
}

这样写简单明了,比起我那个桶强多了,然后感谢这道题让我知道了^,以后在做别的题的时候也可以用到。

以上为我这道题的全部思路与解法,如果有什么不对的地方,还请各位大佬及时向我纠正。

原文地址:https://www.cnblogs.com/dgdger/p/12848664.html