HDU 2034 (人見人愛A-B)(超級簡單做法+經驗分享)

人見人愛A-B

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 129158 Accepted Submission(s): 36180

Problem Description

參加過上個月月賽的同學一定還記得其中的一個最簡單的題目,就是{A}+{B},那個題目求的是兩個集合的並集,今天我們這個A-B求的是兩個集合的差,就是做集合的減法運算。(當然,大家都知道集合的定義,就是同一個集合中不會有兩個相同的元素,這裏還是提醒大家一下)
呵呵,很簡單吧?

Input

每組輸入數據佔1行,每行數據的開始是2個整數n(0<=n<=100)和m(0<=m<=100),分別表示集合A和集合B的元素個數,然後緊跟着n+m個元素,前面n個元素屬於集合A,其餘的屬於集合B. 每個元素爲不超出int範圍的整數,元素之間有一個空格隔開.
如果n=0並且m=0表示輸入的結束,不做處理。

Output

針對每組數據輸出一行數據,表示A-B的結果,如果結果爲空集合,則輸出“NULL”,否則從小到大輸出結果,爲了簡化問題,每個元素後面跟一個空格.

Sample Input

3 3 1 2 3 1 4 7
3 7 2 5 8 2 3 4 5 6 7 8
0 0

Sample Output

2 3
NULL
這道A-B的題理論上來說是水題,但對我來說不是水題,我又學習到了很多東西啦!
首先A-B就是去除A中的元(該元素既在A中又在B中重複的元素)
見下面代碼:

很不幸的是這段代碼AC不掉,爲什麼呢?
我也不知道爲什麼
這段代碼很好懂
1先將數組放進去
2將a數組排序
3在b中找到和a相同的數,在b中若有一個a數組相同的,a數組總個數減一,且c數組在a數組相同元素(**此元素與b數組元素相同**)下的位置把c數組該位置置爲-1
c數組是標記數組一方便輸出
思路一目瞭然清晰
#include<iostream>
using namespace std;
int main()
{
	int n,m;
	int a[101],b[101],c[101]={0};
	while(cin>>n>>m&&(n||m))
	{
		int s=n,t=m;
		int i,j;
		for(i=0;i<n;i++)
			cin>>a[i];
		for(j=0;j<m;j++)
			cin>>b[j];
		int temp;
		//先進行冒泡排序
		for(i=0;i<n;i++)
		{
			for(j=0;j<n-i-1;j++)
			{
				if(a[j]>a[j+1])
				{
					temp=a[j];
					a[j]=a[j+1];
					a[j+1]=temp;
				}
			}
		}
		for(i=0;i<n;i++)
		{
			for(j=0;j<m;j++)
			{
				if(a[i]==b[j])
				{
					s--;
					c[i]=-1;
					break;
				}
			}
		}
		if(s==0)
			cout<<"NULL"<<endl;MK
		else
		{
			
			for(i=0;i<n;i++)
			{
				if(c[i]==0)
					cout<<a[i]<<" ";
			}
			cout<<endl;
		}			
	}
	return 0;
}
但是這段代碼是無法通過的!不是語法,也不是代碼本身的問題。也不是題意的問題

問題在於:
因爲我刷HDU 前面幾道題的時候有的題目只需要輸出格式滿足最後題目條件即可,比如我上面的代碼,上面的代碼中a數組(A集合)自始至終都沒有改變任何元素,僅僅只做了個排序,然後輸出的時候用簡單的算法來保證輸出和題目中的OUTPUT是一某一樣的
這種操作相當於把表面修改一下,本質內容沒有改變

其實這種做法的確沒錯,我前面幾道HDU 題目就是這麼幹的,沒有任何問題的

問題是有的題目需要改變原來的值,比如本題的A-B,那麼A集合肯定是要變的呀,怎麼可能還是原來的集合啊!
所以對應的a數組需要變化

所以只需要小小的改變即可,代碼如下
在此我特別不提倡使用歸併排序,沒必要呀!然後啥的!麻煩的

只需要對a數組的進行排序就行啦,然後將與b數組相等的a數組的元素刪除即可!
#include<iostream>
using namespace std;
int main()
{
	int n,m;
	int a[101],b[101];
	while(cin>>n>>m&&(n||m))
	{
		int s=n,t=m;
		int i,j;
		for(i=0;i<n;i++)
			cin>>a[i];
		for(j=0;j<m;j++)
			cin>>b[j];
		int temp;
		//先進行冒泡排序
		for(i=0;i<n;i++)
		{
			for(j=0;j<n-i-1;j++)
			{
				if(a[j]>a[j+1])
				{
					temp=a[j];
					a[j]=a[j+1];
					a[j+1]=temp;
				}
			}
		}
		int k=0;
		for(i=0;i<n;i++)
		{
			int flag=1;
			for(j=0;j<m;j++)
			{
				if(a[i]==b[j])
				{
					s--;
					flag=-1;
					break;
				}
			}
			if(flag==1)
				a[k++]=a[i];
		}
		if(s==0)
			cout<<"NULL"<<endl;
		else
		{
			
			for(i=0;i<k;i++)
			{
				cout<<a[i]<<" ";
			}
			cout<<endl;
		}			
	}
	return 0;
}

這裏也可以使用c數組,來把a數組中的元素且不同於b數組中的元素放在c數組中,其他的基本一樣。代碼如下,有興趣的可以看一下!

#include<iostream>
using namespace std;
int main()
{
	int n,m;
	int a[101],b[101],c[101];
	while(cin>>n>>m&&(n||m))
	{
		int s=n,t=m;
		int i,j;
		for(i=0;i<n;i++)
			cin>>a[i];
		for(j=0;j<m;j++)
			cin>>b[j];
		int temp;
		//先進行冒泡排序
		for(i=0;i<n;i++)
		{
			for(j=0;j<n-i-1;j++)
			{
				if(a[j]>a[j+1])
				{
					temp=a[j];
					a[j]=a[j+1];
					a[j+1]=temp;
				}
			}
		}
		int k=0;
		for(i=0;i<n;i++)
		{
			int flag=1;
			for(j=0;j<m;j++)
			{
				if(a[i]==b[j])
				{
					s--;
					flag=-1;
					break;
				}
			}
			if(flag==1)
				c[k++]=a[i];
		}
		if(s==0)
			cout<<"NULL"<<endl;
		else
		{
			
			for(i=0;i<k;i++)
			{
				cout<<c[i]<<" ";
			}
			cout<<endl;
		}			
	}
	return 0;
}

雖然是水題但是滿滿的收穫!

有的題目不需要改變原來的值,修改表面並保證輸出結果和output一樣即可!

有的題目必須改變原來的值,既要修改本質內容,也需要修改表面並保證輸出結果和output一樣即可

什麼時候需要改變,什麼時候不需要改變。需要看題目題意而定,根據題意來做出選擇!

笨辦法是在確保代碼正確,測試結果正確等等正確成功的條件下進行測試即可!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章