Codeforces Round #Pi (Div. 2) (STL专场)

Codeforces Round #Pi (Div. 2)

A - Lineland Mail

水题,拼手速。

/*
* @author Novicer
* language : C++/C
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
#define INF 2147483647
#define cls(x) memset(x,0,sizeof(x))
#define rise(i,a,b) for(int i = a ; i <= b ; i++)
using namespace std;
const double eps(1e-8);
typedef long long lint;

const int maxn = 100000 + 5;
lint x[maxn];
int main(){
	int n;
	cin >> n;
	for(int i = 1 ; i <= n ; i++)
		scanf("%I64d",&x[i]);
	sort(x+1,x+n+1);//其实不用排序的:)
	cout << x[2] - x[1] << " " << x[n] - x[1] << endl;
	for(int i = 2 ; i < n ; i++){
		lint mi = min(x[i] - x[i-1] , x[i+1] - x[i]);
		lint ma = max(x[n] - x[i] , x[i] - x[1]);
		printf("%I64d %I64d\n",mi,ma);
	}
	cout << x[n] - x[n-1] << " " << x[n] - x[1] << endl;
	return 0;
}

B - Berland National Library

预处理一开始没出现过的“- x”,在开头补充“+ x"

然后用set模拟进入与离开的过程,输出最大的set容量。

/*
* @author Novicer
* language : C++/C
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
#define INF 2147483647
#define cls(x) memset(x,0,sizeof(x))
#define rise(i,a,b) for(int i = a ; i <= b ; i++)
using namespace std;
const double eps(1e-8);
typedef long long lint;
bool vis[1000005];
int del[105],add[105],s[105];
set<int>lib;
int main(){
//	freopen("input.txt","r",stdin);
	int n;
	cin >> n;
	cls(vis);
	cls(del);cls(add);cls(s);
	int ans = 0;
	int tmp;
	int x = 0;
	int ans1 = 0 , ans2 = 0;
	for(int i = 1 ; i <= n ; i++){
		char c;
		cin >> c;
		if(c == '+'){
			cin >> add[i];
			vis[add[i]] = true;
		}
		else{
			int num;
			cin >> num;
			if(!vis[num]){
				x++;
				s[x] = num;
				del[i] = num;
			}
			else{
				del[i] = num;
			}
		}
	}
	for(int i = 1 ; i <= x ; i++) lib.insert(s[i]);
	ans = lib.size();
	for(int i = 1 ; i <= n ; i++){
		if(add[i] != 0){
			lib.insert(add[i]);
		}
		else if(del[i] != 0){
			lib.erase(del[i]);
		}
		tmp = lib.size();
		ans = max(tmp , ans);
	}
	cout << ans << endl;
	return 0;
}

C - Geometric Progression

枚举每一个元素a[i],将其当做等比数列的第二项,如果a[i]/k 与 a[i]*k存在,则将a[i]/k 与 a[i]*k的数量相乘并累加。

英文题解好像解释的更清楚些。。

Let‘s solve this problem for fixed middle element of progression. This means that if we fix element
ai then the progression must consist of
ai?/?k and
ai·k elements. It could not be possible, for example, if
ai is not divisible by
k ().

For fixed middle element one could find the number of sequences by counting how many
ai?/?k elements are placed left from fixed element and how many
ai·k are placed right from it, and then multiplying this numbers. To do this, one could use two associative arrays
Al and
Ar, where for each key
x will be stored count of occurences of
x placed left (or right respectively) from current element. This could be done with map structure.

Sum of values calculated as described above will give the answer to the problem.

/*
* @author Novicer
* language : C++/C
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
#define INF 2147483647
#define cls(x) memset(x,0,sizeof(x))
#define rise(i,a,b) for(int i = a ; i <= b ; i++)
using namespace std;
const double eps(1e-8);
typedef long long lint;

const int maxn = 2 * 100000 + 5;
lint a[maxn];
map<lint , lint> l;
map<lint , lint> r;
int main(){
//	freopen("input.txt","r",stdin);
	int n;
	lint k;
	cin >> n >> k;
	for(int i = 1 ; i<= n ; i++){
		scanf("%I64d",&a[i]);
		r[a[i]]++;
	}
	lint ans = 0;
	for(int i = 1 ; i <= n ; i++){
		r[a[i]]--;
		if(a[i] % k == 0)
			ans += l[a[i]/k] * r[a[i]*k];
		l[a[i]]++;
	}
	cout << ans << endl;
	return 0;
}

D - One-Dimensional Battle Ships

很有意思的一道题,长度为n的空间放着k条长度为a的船,且船不重叠,Alice给你m个宣称miss(即没有船)的位置,判断Alice是否撒谎,若撒谎输出第一次可以发现矛盾的位置。

思路:

题解思路太棒!简单来说就是判断Alice说的位置将空间分为两个部分,计算出这两个部分各能容纳几艘船,加起来与k比较,大于则撒谎。

For problem D, simply use a map structure to record the free space (a consecutive empty square without shotpoint) on a shotpoint‘s left and right.

You can use the lower_bound and upper_bound functions to find the nearest shotpoint, and update them.

When a shot happens a free space will be broken into 2, so calculate the sum of max number of ships of those 2 spaces and subtract it from the global sum of max number of ships.

Calculate the maximum number of ships could be placed in the space: (space+1)/(a+1)

(global sum of max number of ships = (n+1)/(a+1) before the 1st shot.)

when the global sum < k just print the current operation number and exit.

/*
* @author Novicer
* language : C++/C
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
#define INF 2147483647
#define cls(x) memset(x,0,sizeof(x))
#define rise(i,a,b) for(int i = a ; i <= b ; i++)
using namespace std;
const double eps(1e-8);
typedef long long lint;

map<int , int> ship;
int n,k,a;

int f(int x){return (x+1)/(a+1);};//计算长度为x区间能容纳几艘船
int main(){
//	freopen("input.txt","r",stdin);
	while(cin >> n >> k >> a){
		ship.clear();
		int m ; cin >> m;
		ship[0] = ship[n+1] = 1;
		int max_sum = f(n);
		bool cheat = false;
		for(int i = 1 ; i <= m ; i++){
			int shot;
			scanf("%d",&shot);
			if(ship.find(shot) != ship.end()) continue;
			ship[shot] = 1;
			int l , r;
			map<int , int>:: iterator low = ship.lower_bound(shot);
			map<int , int>:: iterator up = ship.upper_bound(shot);//low-1与up分别是最靠近shot的左右位置
			l = (--low)->first;
			r = up->first;
			max_sum -= f(r - l - 1);
			max_sum += f(r - shot - 1) + f(shot - l - 1);
			if(max_sum < k){
				cheat = true;
				cout << i << endl;
				return 0;
			}
		}
		if(!cheat)
			cout << -1 << endl;
	}
	return 0;
}

版权声明:博主表示授权一切转载:)

时间: 2024-10-10 07:00:34

Codeforces Round #Pi (Div. 2) (STL专场)的相关文章

map Codeforces Round #Pi (Div. 2) C. Geometric Progression

题目传送门 1 /* 2 题意:问选出3个数成等比数列有多少种选法 3 map:c1记录是第二个数或第三个数的选法,c2表示所有数字出现的次数.别人的代码很短,思维巧妙 4 */ 5 /************************************************ 6 * Author :Running_Time 7 * Created Time :2015-8-6 1:07:18 8 * File Name :C.cpp 9 *************************

构造 Codeforces Round #Pi (Div. 2) B. Berland National Library

题目传送门 1 /* 2 题意:给出一系列读者出行的记录,+表示一个读者进入,-表示一个读者离开,可能之前已经有读者在图书馆 3 构造:now记录当前图书馆人数,sz记录最小的容量,in数组标记进去的读者,分情况讨论一下 4 */ 5 /************************************************ 6 * Author :Running_Time 7 * Created Time :2015-8-6 0:23:37 8 * File Name :B.cpp 9

Codeforces Round #Pi (Div. 2) (ABCD题解)

比赛链接:http://codeforces.com/contest/567 听说Round #Pi的意思是Round #314... A. Lineland Mail time limit per test:3 seconds memory limit per test:256 megabytes All cities of Lineland are located on the Ox coordinate axis. Thus, each city is associated with it

Codeforces Round #Pi (Div. 2) E. President and Roads (最短路+强连通求割边)

题目地址:codeforces #pi (DIV2) E 题目很水..就是先求两边最短路,然后把可能为最短路的边挑出来,然后判断是否yes只需要转化成无向图跑一遍tarjan,找出割边,割边就是yes,然后剩下的边就让它的值为最短路-1就行了,如果-1后变成了非正数,就是no. 但是!!!居然卡spfa!!那是不是说cf以后就不能用可以卡的算法了..完全可以出组数据来卡这些算法...比如spfa,isap... 于是为了这题,又看了一遍迪杰斯特拉算法.. 代码如下: #include <cstd

Codeforces Round #Pi (Div. 2) B Berland National Library

思路:对于这道题,一开始并没有什么思路,但后来想了下,其实就是维护一个集合,每一个人都是不同的元素,满足了集合的互异性,而要求这个图书馆最小的容纳量,其实就是求这个集合的最大的元素量,假设在某个时刻集合里存在M个元素,是集合从开始到结束出现过的元素个数的最大值,那么就是这个图书馆的最小容纳量,如果最小容纳量比M小,那怎么容得下M个人?对于+,   他之前肯定是没进或者之前出来股,无论怎样,都要加进集合. 对于一个集合的操作,在cf种时间为上的比赛,自然选用stl的set,如果各位有更好的思路或实

Codeforces Round #Pi (Div. 2)(A,B,C,D)

A题: 题目地址:Lineland Mail #include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <sstream> #include <algorithm> #include <set> #include <queue> #include

Codeforces Round #Pi (Div. 2) —— C-Geometric Progression

题意: 现在有n个数,然后给出一个数k(代表的是等比数列中的那个公比),然后第二行给出n个数,代表的是这个序列. 最后的问题是叫你找出在这个序列中满足公比为k的三个数有几种,并输出方案总数. 思路: 这道题很巧妙啊,用到了map. 首先我们先记录下每种数出现过了几次,这里因为数太大了,直接用数组存会爆掉,所以改用map. 我们需要两个map,分别记为mp1,mp2. 然后在for的过程中,我们是以当前的那个数为第二项,然后去寻找它的mp1[a[i]*k](也就是第三项),寻找它的mp2[a[i]

Codeforces Round #Pi (Div. 2) —— D One-Dimensional Battle Ships

题目的意思是: 现在有一个长度为n,宽为1的方格,在上面可以放大小为1*a船,然后输入为n,k,a:分别为平地的大小,船的数量,船的长度. 一个叫alice的人已经在地图上摆好了船的位置. 然后bob总共可以有m次攻击的机会,然后他每次攻击的点为xi,但是alice并不会告诉它有没有打中(也就是说每次都认为他是miss的),问你,bob可以在第几次攻击的时候推测出alice在撒谎,如果推测不出来则输出-1. 这里每两条相邻的船不能相互接壤. 思路: 用set来维护每一段的区间. 首先,我们最多可

Codeforces Round #Pi (Div. 2)——set——Berland National Library

Berland National Library has recently been built in the capital of Berland. In addition, in the library you can take any of the collected works of Berland leaders, the library has a reading room. Today was the pilot launch of an automated reading roo