[NBOJ0023][Easy Problem]

[題目要求]

http://acm.bupt.edu.cn/onlinejudge/newoj/showProblem/show_problem.php?problem_id=23php

[題目涉及的相關理論與算法]
位操做與位運算ios

[題目中須要注意的地方]
就是對於大數據查找等處理,雖然要求很簡單,可是常規的思路解決不了問題。。。由於會超出時間。算法

[思路過程]
一開始覺得真是大水題了。。題目要求真的很簡單,就是對一組數據找出配不成對的一個數,我一開始的思路就是創建一個list容器,而後每次查找,只要是新數據就加到尾部,是出現過的數據就刪除掉原來的數據。這樣,在循環結束後只剩下題目要求的那個數。代碼寫出來以下:數組

#include<iostream>
#include<list>
#include<algorithm>
using namespace std;
void casesolve(int n)
{
	list<long long> table;
	int numLoop = 2*n-1;
	long long num;

	while((numLoop--) != 0)
	{
		cin>>num;
		list<long long>::iterator key;
		key = find(table.begin(),table.end(),num);//find方法。
		if( key != table.end())  //這裏就是核心部分,若是老數據,則返回的迭代器就不是末尾。
		{
			table.erase(key);
		}
		else table.push_back(num);//新數據則加入到列表尾部。
	}
	cout<<table.front()<<endl;//最後只剩下要求的數據。
}

int main()
{
	//freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
	int n;
	cin>>n;
	while(n != 0)
	{
		casesolve(n);
		cin>>n;
	}
	//fclose(stdin);
	//fclose(stdout);
        return 0;
}

而後上面的代碼提交以後,就是LTE。。我設想多是find方法效率低?就打算用數組寫一個,本身寫查找函數,可是仍是以爲基本上效率也不會差太多,也多是erase的操做問題,可是按照個人算法,若是不使用erase不行。
最後以爲在我接觸的東西中,基本上沒有好辦法處理了。。這時去網上查了一下,而後發現原來,是能夠用位的異或運算解決的! 好強大的想法,我以前是不管如何不能想到的,異或運算有以下的重要性質:函數

  1. a ^ a = 0
  2. a ^ 0 = a
  3. a ^ b ^ c = a ^ ( b ^ c )

這三條性質正好能夠解決此題,設想輸入數據後,全部成對的數據都會和本身異或掉,變成零,而後剩下的數據與0異或仍是本身。因此將每次的結果異或後,最後剩下的就是沒有成對的數!
代碼以下:oop

[代碼]大數據

#include<iostream>
using namespace std;
void casesolve(int n)
{
	long long result=0,temp=0;
	int numLoop = 2*n-1;
	while((numLoop--)!=0)
	{
		cin>>temp;
		result = result ^ temp; //這就是核心的部分,真是很是的巧妙!
	}
	cout<<result<<endl;
}
int main()
{
	int n;
	cin>>n;
	while(n != 0)
	{
		casesolve(n);
		cin>>n;
	}
	return 0;
}

[尾聲]
選對了方法以後,就會以爲一會兒變得很簡單了,今天雖然這道題很簡單,可是對個人思路有了很大的啓發。考慮問題的處理上,不少時候能夠嘗試跳出慣性的框框,會一會兒豁然開朗!
spa

相關文章
相關標籤/搜索