CodeChef 2015年12月问题

CHEFST

(1)问题描述:

(2)要点:[1,m*(m+1)/2]内的每个数都可以表示为[1,m]的不同整数的和

(3)代码:

#include <stdio.h>

int main()
{
	unsigned int nCases = 0;scanf("%d",&nCases);
	for(unsigned int iCases = 1;iCases <= nCases;++iCases)
	{
		unsigned long long n1 = 0,n2 = 0,m = 0;
		//scanf("%I64d%I64d%I64d",&n1,&n2,&m);
		scanf("%lld%lld%lld",&n1,&n2,&m);
		if(n1 < n2) { n1 ^= n2;n2 ^= n1;n1 ^= n2; }
		unsigned long long sum = (m+1)*m/2,ans = 0;
		if(n2 < sum) ans = n1 - n2;
		else ans = n1 - sum + n2 - sum;
		printf("%llu\n",ans);
	}
	return 0;
}


PLANEDIV

(1)问题描述:

(2)要点:计算平行但不共线的最大的集合大小

(3)代码:

#include <stdio.h>
#include <set>
#include <map>
using std::set;
using std::map;

// 平行但不共线
unsigned int gcd(unsigned int a,unsigned int b)
{
	if(a < b) return gcd(b,a);
	if(0 == b) return a;
	if(1 == b) return 1;
	return gcd(b,a%b);
}

template<class data_t>
class fraction_t
{
	data_t	numerator;	 // 分子
	data_t	denominator;	 // 分母
public:
	fraction_t(const data_t& n,const data_t& d):numerator(n),denominator(d) { if(denominator < 0) { denominator = 0 - denominator;numerator = 0 - numerator; }  }	 // 分母为非负
public:
	bool operator<(const fraction_t& rhs)const { return numerator*rhs.denominator < denominator*rhs.numerator; }
	bool operator==(const fraction_t& rhs)const { return numerator*rhs.denominator == denominator*rhs.numerator; }
	bool operator<=(const fraction_t& rhs)const { return numerator*rhs.denominator <= denominator*rhs.numerator; }
};

int main()
{
	typedef fraction_t<long long> Fraction;
	typedef std::pair<int,int> Pair;
	typedef std::pair<Pair,int> Truple;
	unsigned int nCases = 0;scanf("%d",&nCases);
	for(unsigned int iCases = 1;iCases <= nCases;++iCases)
	{
		unsigned int n = 0;scanf("%d",&n);
		set<Truple> table;
		map<Fraction,size_t> data;
		unsigned int ans = 1;
		for(unsigned int i = 0;i < n;++i)
		{
			int a = 0,b = 0,c = 0;
			scanf("%d%d%d",&a,&b,&c);
			int d = gcd(a>0?a:-a,gcd(b>0?b:-b,c>0?c:-c));
			a /= d;b /= d;c /= d;
			if(a < 0) { a = 0 - a;b = 0 - b;c = 0 - c; }
			else if(0 == a && b < 0) { b = 0 - b;c = 0 - c; }
			Truple u;u.first.first = a;u.first.second = b;u.second = c;
			if(table.find(u) != table.end()) continue;
			table.insert(u);
			map<Fraction,size_t>::const_iterator itFind = data.find(Fraction(a,b));
			unsigned int count = 0;
			if(itFind != data.end()) count = itFind->second;
			++ count;
			if(count > ans) ans = count;
			data[Fraction(a,b)] = count;
		}
		printf("%u\n",ans);
	}
	return 0;
}


ORACLCS

(1)问题描述:

(2)要点:若字符串中有x个a,y个b,则与m个a求LCS可以知道必然不超过x;同时若与m个b求LCS可以知道必然不超过y

(3)代码:

#include <stdio.h>
#include <string.h>
#include <assert.h>
// 若字符串中有x个a,y个b,则与m个a求LCS可以知道必然不超过x;同时若与m个b求LCS可以知道必然不超过y
int main()
{
	static const size_t buff_size = 1000;
	char buff[buff_size] = { 0 };
	unsigned int nCases = 0;scanf("%d",&nCases);
	for(unsigned int iCases = 1;iCases <= nCases;++iCases)
	{
		unsigned int n = 0,ans = buff_size;scanf("%d",&n);
		for(unsigned int i = 0;i < n;++i)
		{
			scanf("%s",buff);
			unsigned int acount = 0,bcount = 0;
			for(size_t k = 0,len = strlen(buff);k < len;++k)
			{
				acount += (buff[k] == 'a');
				bcount += (buff[k] == 'b');
			}
			if(acount < ans) ans = acount;
			if(bcount < ans) ans = bcount;
		}
		printf("%u\n",ans);
	}
	return 0;
}


(1)问题描述:

(2)要点:转换为异或操作,+用1表示,-用0表示。问题转换为在n个数中,有多少个不同的子集合,其异或结果为给定值v。即求异或方程组的解的个数。

(3)代码:不包括高斯消元解异或方程组的模板代码

#include <stdio.h>
#include <assert.h>
#include <string.h>

static unsigned int quick_modexp(unsigned int a,unsigned int module,unsigned long long x)
{
	unsigned long long ret = 1,product = a%module;
	for(;0 != x;x >>= 1)
	{
		if(x&1) ret = (product*ret)%module;
		product = (product*product)%module;
	}
	return (unsigned int)(ret);
}

int main()
{
	static const size_t bitcount = 10;
	static const size_t maxn = 100000;
	static const unsigned int module = 1000000007;
	typedef gauss_jordan_elimination<int,long long> gje;
	static const size_t buff_size = 100;
	char buff[buff_size] = { 0 };
	unsigned int* ans = new unsigned int[maxn];
	unsigned int nCases = 0;scanf("%d",&nCases);
	for(unsigned int iCases = 1;iCases <= nCases;++iCases)
	{
		unsigned int n = 0;scanf("%s%d",buff,&n);
		gje slover(bitcount,n);
		for(size_t i = 0;i < strlen(buff);++i)
		{
			slover(i,n) = (buff[i] == 'w');
		}
		memset(ans,0,sizeof(unsigned int)*maxn);
		for(unsigned int i = 0;i < n;++i)
		{
			scanf("%s",buff);
			for(size_t k = 0;k < strlen(buff);++k)
			{
				slover(k,i) = (buff[k] == '+');
			}
		}
		unsigned int count = slover.xor_slove(ans,n);
		unsigned int ret = 0;
		if(count != gje::NO_ANSWER) ret = quick_modexp(2,module,count);
		printf("%u\n",ret);
	}
	delete[] ans;
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值