1. 程式人生 > >POJ 3484 Showstopper 字首和思想+二分+輸入處理

POJ 3484 Showstopper 字首和思想+二分+輸入處理

題目:

Showstopper
Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 2457Accepted: 739

Description

Data-mining huge data sets can be a painful and long lasting process if we are not aware of tiny patterns existing within those data sets.

One reputable company has recently discovered a tiny bug in their hardware video processing solution and they are trying to create software workaround. To achieve maximum performance they use their chips in pairs and all data objects in memory should have even number of references. Under certain circumstances this rule became violated and exactly one data object is referred by odd number of references. They are ready to launch product and this is the only showstopper they have. They need YOU

 to help them resolve this critical issue in most efficient way.

Can you help them?

Input

Input file consists from multiple data sets separated by one or more empty lines.

Each data set represents a sequence of 32-bit (positive) integers (references) which are stored in compressed way.

Each line of input set consists from three single space separated 32-bit (positive) integers X Y Z and they represent following sequence of references: X, X+Z, X+2*Z, X+3*Z, …, X+K*Z, …(while (X+K*Z)<=Y).

Your task is to data-mine input data and for each set determine weather data were corrupted, which reference is occurring odd number of times, and count that reference.

Output

For each input data set you should print to standard output new line of text with either “no corruption” (low case) or two integers separated by single space (first one is reference that occurs odd number of times and second one is count of that reference).

Sample Input

1 10 1
2 10 1

1 10 1
1 10 1

1 10 1
4 4 1
1 5 1
6 10 1

Sample Output

1 1
no corruption
4 3

題意:

多組資料。每組資料之間由若干空行分隔開。

對於一組資料,由若干行構成,每行有三個32位整數X,Y,Z, 用來表示一個數列:X, X+Z, X+2*Z, X+3*Z, …, X+K*Z, …(X+K*Z)<=Y)。比如 X = 3 , Y = 9 ,  Z = 2, 表示的數列為:3,5,7,9。

這樣一組資料若有n行,就描述了n個數列。輸入保證了這n個數列中出現的數字的次數至多有一個為奇數。 若存在這樣一個數字出現奇數次,那麼輸出這個數字與它出現的次數,否則輸出"no corruption".

思路:

由於保證了出現的所有數字中至多有一個為奇數。那麼如果在k這個數字出現的次數為奇數,那麼比k小的所有數字的次數字首和都為偶數,比k大的所有數字次數字首和均為奇數。我們可以根據這個性質假定答案進行二分求解,第一個使字首和變為奇數的數字就是答案。

eg:樣例3.  

1 10 1
4 4 1
1 5 1
6 10 1

數列1:1,2,3,4,5,6,7,8,9,10

數列2:4

數列3:1,2,3,4,5

數列4:6,7,8,9,10

數字   :1 , 2 ,3 , 4 ,5 , 6 , 7 , 8 , 9 ,10

次數   :2 , 2 , 2 ,3 ,2 , 2 , 2 , 2 , 2 , 2

字首和:2 , 4 ,6 ,9 ,11,13,15,17,19,21

                                  ^^^^^^^^^^^^^^^^^^ 

最後要注意的細節就是這個噁心的輸入了。由於每組資料行數未定,中間的空行未定,那麼我只能通過有無空行來判斷一組資料是否輸入完了(x,y,z的值也就要由sscanf讀入了)。這就會導致最後一組資料後面如果沒有空行就無法輸出,最終在迴圈外面又加了一次處理才能有了輸出。。

程式碼:

#include<cstdio>  
#include<cstdlib>  
#include<cmath>  
#include<cstring>  
#include<iostream>  
#include<algorithm>  
#include<queue>  
#include<map>  
#include<stack> 
#include<set>
#define sd(x) scanf("%d",&x)
#define ss(x) scanf("%s",x)
#define sc(x) scanf("%c",&x)
#define sf(x) scanf("%f",&x)
#define slf(x) scanf("%lf",&x)
#define slld(x) scanf("%lld",&x)
#define me(x,b) memset(x,b,sizeof(x))
#define pd(d) printf("%d\n",d);
#define plld(d) printf("%lld\n",d);
#define eps 1.0E-8
// #define Reast1nPeace

typedef long long ll;

using namespace std;

const ll INF = 0x3f3f3f3f3f3f;

struct node{
	ll x,y,z;
	node(ll x,ll y,ll z){
		this->x = x , this->y = y , this->z = z;
	}
};

vector<node> v;

ll judge(ll m){  
	int len = v.size();
	ll sum = 0;
	for(int i = 0  ; i<len ; i++){
		if(m<v[i].x) continue;
		ll maxn = min(m,v[i].y);
		sum += (maxn-v[i].x)/v[i].z + 1; 
	}	
	return sum;
}

void solve(){
	ll l = 1 ; ll r = INF;
	ll ans = 0;
	while(l<=r){
		ll mid = (l+r)>>1;
		if(judge(mid)&1){
			ans = mid;
			r = mid-1;
		}
		else{
			l = mid+1;
		}
	}	
	if(ans == 0){
		cout<<"no corruption"<<endl;
	}
	else{
		cout<<ans<<" "<<judge(ans)-judge(ans-1)<<endl;
	}
}

int main(){
#ifdef Reast1nPeace
	freopen("in.txt", "r", stdin);
//	freopen("out.txt", "w", stdout);
#endif
	char str[20]; 
	bool flag = 0;
	while(gets(str)){
		if(strlen(str) == 0){
			if(flag){
				solve();
				flag = 0;	
				v.clear();
			} 
			continue;
		}
		flag = 1;
		ll x,y,z;
		sscanf(str,"%lld %lld %lld",&x,&y,&z);
		v.push_back(node(x,y,z));
	}
	if(flag)solve(); 
	return 0;
}