这套题是我上周日, 就是前天打得一场组队赛, 题目不太好找
题目链接:http://codeforces.com/gym/100861 在virtual judge 上也可以提交哦!
A ACM ICPC Rules:
题目大意: 有很多所高校参加预选赛, 并在预选赛取得了排名, 但是对于每所学校, 除了MSU有4个名额之外其他大学只有两个名额( 也就是说, 只有每个大学的前2名进决赛(MSU前四名)&& 最多有10个队伍进入决赛), 高中队伍不能进入决赛。 给出预选赛的排名, 输出可以进入决赛的名单,( 最多十个 )
题目分析: 这道题还是看题解出来的, 感觉自己做的题太少了, 很多题能做出来就是做的方法添麻烦, 所以以后要多做题夯实, 首先如果遇到"SCH"就continue, 创建一个MAP<string, int>记录每种字符串出现的次数, 再创建一个vector<pair<string, string>> V 储存进入MSU 的排名。
#include <iostream> #include <vector> #include <string> #include <map> #include <algorithm> using namespace std; vector<pair<string, string>> V; map<string, int> MAP; int main() { int n; while( cin >> n ) { int lim = 0; for( int i = 1; i <= n; i++ ) { string a, b; cin >> a >> b; if( a == "SCH" ) continue; else { if( a == "MSU" ) lim = 4; else lim = 2; } if( MAP[a] < lim ) { MAP[a]++; V.push_back( make_pair( a, b ) ); } } int ans1 = min( 10, (int)V.size() ); cout << ans1 << endl; for( int i = 0; i < ans1; i++ ) { cout << V[i].first << " "; cout << V[i].second << endl; } } return 0; }
G Genesis Project:
题目大意:给若干个点, 每两个点会生成一个新的点, 位置是两点连线的中点, 当前点都有"孩子"后当前点才会消失, 发生两个点的位置正好的重合的情况的“繁殖次数”是多少?
题目分析: 首先要知道任意四边形的中点一定是平行四边形, 而平行四边形对角连线的中点重合 , 所以说,当点数大于4的时候, 最多繁殖次数就为2!妈的这点要是想到早就做上来了, 还是太蠢, 做的题实在是太少!然后答案为1的就是一个点恰好在两个点的中点的位置上, ( n >= 4 ) , 当只有 <= 3 个点的时候, 无论怎样都不可能重合!( 但是有一种特殊情况就是三个点 , 其中一点是另外两个点的中点, 这时本来应该输出1的, 但是没特殊处理也给过了(可能是数据水) )
然后再说一下怎么找到两点重合, 首先建一个pair< int, int > P 的SET容器 , 来储存点的x , y坐标, 然后将P 推入SET 中, 最后两两枚举, 如果 SET.count( P ) == 1 就break掉然后输出1; 如果 n <= 3 则输出0 ; 其余的就用以上方法寻找, 如果寻找未果就输出2~!
附上代码:
#include <cstdio> #include <set> #include <algorithm> #include <cstring> using namespace std; set< pair< int, int > > S; pair< int, int > a[1004]; int n; int main() { scanf( "%d", &n ); S.clear(); memset( a, 0, sizeof( a ) ); for( int i = 1; i <= n; i++ ) { scanf( "%d%d", &a[i].first, &a[i].second ); } if( n <= 3 ) { printf( "0\n" ); return 0; } for( int i = 1; i <= n; i++ ) { for( int j = i + 1; j <= n; j++ ) { pair< int, int > P; P = make_pair( a[i].first + a[j].first, a[i].second + a[j].second ); if( S.count( P ) ) { printf( "1\n" ); return 0; } S.insert( P ); } } printf( "2\n" ); return 0; }
L. Lucky Bonds:
题目大意:给出Lucky number 的定义, 对于前N个数字和后N个数字之和相等, 比如“1340” 1 + 3 = 4 + 0 则这个数字就是Lucky Number,显然数字的位数为2 * N 。 输入一个N, 求长度为2 * N 最大连续非幸运数区间的左区间和右区间。
题目分析: 这道题是个构造题, 但是首先看到N的范围很小 , 1 ~ 10, 所以在想能不能打表将结果打出来, 暴力很简单, 当N = 1 , 2, 3 的时候答案分别是 89, 98; 9899, 9998;
998999, 999998; 所以后面的结果直接打表出来就可以了, 代码很丑。
然后就是构造方法, 很明显这道题是一个special judge, 所以我以8 , 9为例, 来构造答案, 假设N = 3, 右端点就是999998, 左端点就为从999998 往左数的第一个幸运数字后的非幸运数字( 有些拗口 , 但是仔细想想还是能想明白 ) ,后三位和为 9 + 9 + 8, 所以前三位只能是8 + 9 + 9 , 9 + 8 + 9, 9 + 9 + 8 , 又因为9 9 8 组合是最靠近999998的( 向左数的第一个lucky number ) 所以构造方法就是, 左区间的端点值为第 N + 1 位为8, 其余为9 :
附上史上最丑的代码,。。。。。。。。
#include <iostream> #include <cstdio> #include <cstring> #include <string> using namespace std; string ans[30] = { " ", " ", "89", "98", "9899", "9998", "998999", "999998", "99989999", "99999998", "9999899999", "9999999998", "999998999999", "999999999998", "99999989999999", "99999999999998", "9999999899999999", "9999999999999998", "999999998999999999", "999999999999999998", "99999999989999999999", "99999999999999999998" }; int main() { int n; while( cin >> n ) { cout << ans[2*n] << endl << ans[2*n+1] << endl; } return 0; }
还有两道题, 过段时间补全!
ACM ICPC 2008–2009 NEERC MSC A, B, C, G, L
原文:http://www.cnblogs.com/FriskyPuppy/p/5998386.html