Codeforces Round #204 (Div. 2)

来源:互联网 发布:oracle sql if 子查询 编辑:程序博客网 时间:2024/05/22 15:18

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;}


原创粉丝点击