poj之旅——3484

题目描述:给出若干组数据,每组数据包括若干个数列,数列给出首项x[i],末项y[i],公差z[i],问对于每组数据的所有数列中,出现奇数次的数字是多少,以及出现了多少次。


题解:

此题堪称继数论以后,第一坑的题目。

首先读入把人难倒了——先用gets读一行,再判断字符串的长度,若为0则表示一组新数据的开始,不为0则用sscanf转化成int类型,对于初学C++的新手。。泪奔。。。

二分结果,定义Sum[mid,i]=C[1]+C[2]+...C[i](i表示是该组数据中的第i个数列,C表示该个数列中小于mid的个数),可以肯定的说,如果mid出现的是奇数次,则Sum也是奇数(因为题目指明只有一个奇数),则范围可以继续缩小,否则将范围扩大。

再者,此题,用stringsteam似乎比较方便(又是一深奥东东,再次泪。。),但会超时,也就是说,比赛时,除了C++的STL库,其他C++的特性都比较慢。。。。

参考程序:

#include<cstdio>
#include<algorithm>
#include<string>
#define INF 0x7f7f7f7f
#define maxn 2100000
using namespace std;
int cnt;
char str[1024];
long long x[maxn],y[maxn],z[maxn];
long long c[maxn];
long long Count(long long limit){
	long long sum=0;
	for (int i=0;i<cnt;i++){
		if (limit>=y[i])sum+=c[i];
		else if (limit>=x[i])sum+=(limit-x[i])/z[i]+1;
	}
	return sum;
}
void solve(){
	long long Bit;
	for (int i=0;i<cnt;i++){
		c[i]=(y[i]-x[i])/z[i]+1;
		Bit^=c[i];
	}
	if (!(Bit & 1)){
		printf("no corruption\n");
		return;
	}
	long long l=0,r=INF;
	while(l<r){
		long long mid=(l+r)>>1;
		if (Count(mid)&1)r=mid;
			else l=mid+1;
	}
	printf("%lld %lld\n",l,Count(l)-Count(l-1));
}
int main(){
	cnt=0;
	while (gets(str)!= NULL){
		if (strlen(str)==0){
			if (!cnt)continue;
			solve();
			cnt=0;
		}else{
			sscanf(str,"%lld %lld %lld",&x[cnt],&y[cnt],&z[cnt]);
			cnt++;
		}
	}
	if (cnt)solve();
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值