Codeforces Round #204 (Div. 2)

A. Jeff and Digits

链接:http://codeforces.com/contest/352/problem/A

描述:给定n个数,每个数字是0或者5,(1<=n<=1000).求一个最大的能被90整除的数。

思路:直接找规律,当5的个数是9的倍数时能被90整除。注意0的个数处理。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
	int n;
	scanf("%d", &n);
	int a[n];
	for (int i = 0; i < n; ++i)
		scanf("%d", &a[i]);
	int num5 = 0, num0 = 0;
	for (int i = 0; i < n; ++i)
	{
		if (a[i] == 5)
			++num5;
		if (a[i] == 0)
			++num0;
	}
	if (num0 == 0)
	{
		printf("-1\n");
		return 0;
	}
	if (num5 < 9 && num0 > 0)
	{
		printf("0\n");
		return 0;
	}
	int t = num5 / 9;
	for (int i = 0; i < t * 9; ++i)
		printf("5");
	for (int i = 0; i < num0; ++i)
		printf("0");
	printf("\n");
	return 0;
}

B. Jeff and Periods

链接:http://codeforces.com/contest/352/problem/B

描述:给定n(1<=n<=10^5)个数的数组,a1,a2.......an (1<=ai<=10^5).求满足这两个条件的所有x:

1.x出现在a数组中。

2.对于所有出现x的位置下表i,这些下标组成等差数列。

思路:我的思路就是用map< int , vector<int> >,把每个数组元素的下标按照升序添加到它所对应的vector中,然后判断vector中的下标是不是等差数列。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
const int M = 100000 + 10;
using namespace std;
int main()
{
	int n;
	scanf("%d", &n);
	map< int, vector<int> > t;
	int val;
	for (int i = 1; i <= n; ++i)
	{
		cin >> val;
		t[val].push_back(i);
	}
	map< int, vector<int> >::iterator it;
	int sum = 0;							//sum  存储符合条件的x的个数
	int res1[M], res2[M];					//res1,res2对应每个x和公差
	for (it = t.begin(); it != t.end(); ++it)
	{
		if ((it->second).size() == 1)
		{
			res1[sum] = it->first;
			res2[sum] = 0;
			sum++;
			continue;
		}
		bool ok = 1;
		int dif = (it->second)[1] - (it->second)[0];
		for (int i = 2; i < (it->second).size(); ++i)
		{
			if ((it->second)[i] - (it->second)[i-1] != dif)
			{
				ok = 0;
				break;
			}
		}
		if (ok)
		{
			res1[sum] = it->first;
			res2[sum] = dif;
			sum++;
		}
	}
	cout << sum << endl;
	for (int i = 0; i < sum; ++i)
	{
		cout << res1[i] << " " << res2[i] << endl;
	}
	return 0;
}

C. Jeff and Rounding(Codeforces Round #204 (Div. 1)A. Jeff and Rounding)

链接:http://codeforces.com/problemset/problem/351/A

描述:首先输入n(1<=n<=2000), 然后是2*n个浮点数,选n对浮点数,每一对浮点数其中一个数下取整,另一个数上取整,然后求2*n个处理后浮点数的和与处理前浮点数的和的差的绝对值的最小值。

即min |(a1+a2+.....+an)-([ai1+aj1]+[ai2+aj2]+.....+[ain+ajn])|
思路:我的思路是这样的,不知道对不对。
先看几个简单的整数函数公式:定义ceil表示上取整,floor表示下取整,fmod表示取小数部分
ceil(x) = floor(x)          当且仅当x为整数
ceil(x) = floor(x) + 1    当且仅当x不是整数
本题每次选取有三种情况:(整数是指a.000的格式)
1.两个整数:前后绝对值之差为0。
2.一个整数一个小数:小数可以是上取整或者下取整,假设ai是整数,ceil(ai) = floor(ai)
min( |ai+aj-floor(ai)-ceil(aj)|, |ai+aj-ceil(ai)-floor(aj)| ) //用上面的两个公式转化
=min( |ai-floor(ai)+aj-floor(aj)-1|, |ai-floor(ai)+aj-floor(aj)| )
=min( |fmod(ai)+fmod(aj)-1|, |fmod(ai)+fmod(aj)| )
=min( |fmod(aj)-1|,abs( fmod(aj)) )
3.两个小数:
min( |ai+aj-floor(ai)-ceil(aj)|, |ai+aj-ceil(ai)-floor(aj)| )
=min( |ai-floor(ai)+aj-floor(aj)-1|, |ai-floor(ai)-1+aj-floor(aj)| )
=|fmod(ai)+fmod(aj)-1|
可以看出,第一种和第三种答案已经固定了,只有第二种需要考虑,即找到zeronum(zeronum<=n)个整数和小数配对,取一个最小值。 而第二种情况的结果就是aj的小数部分要不要减去1的问题。
为了避免精度问题,可以都当作整数读取。
#include <iostream>
#include <functional>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int INF = 0x7fffffff;
int main()
{
	int n;
	scanf("%d", &n);
	int intpart, facpart, sum = 0, zeronum = 0;
	for (int i = 0; i < n * 2; ++i)
	{
		scanf("%d.%d", &intpart, &facpart);
		sum += facpart;
		if (facpart != 0)
			++zeronum;
	}
	int L = max(0, zeronum - n);
	int R = min(zeronum, n);
	int ans = INF;
	for (int i = L; i <= R; ++i)
		ans = min(ans, abs(sum - i*1000));
	printf("%d.%03d\n", ans / 1000, ans % 1000);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PegasusWang_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值