2018-2019 ACM-ICPC, Asia Seoul Regional Contest 补题|题解

咕咕咕 慢速补题中qwq(部分题只有代码没有题解,有时间会补上的qwq)
补题题号:ABDEFGKL

A- Circuits

线段树+扫描线的题!
显而易见发现其中一维坐标没有什么用,直接记录另外一维即可。(当成线段)
扫描线部分:我们可以把每条线段[a, b]拆成两个点:a, b+1来看待。a是入点坐标,对答案的贡献+1;b+1是出点坐标(不是b,是因为如果有线在b坐标时,仍然可以将该线段加入贡献),对答案的贡献-1.
线段树部分:在扫描线部分我们可以处理一条线段横切矩形群的情况,当我们固定那一条切割线的时候,还有一条切割线,这时候需要我们用logn左右的时间复杂度将其处理出来。所以自然能想到用线段树维护单点最大值。

#include<bits/stdc++.h>
#define MAXN 2000010
using namespace std;
int n, cnt;
int pre[MAXN];
struct Node2{
	int pos, v, low, high;
	friend bool operator < (struct Node2 x, struct Node2 y){
		if(x.pos != y.pos) return x.pos < y.pos;
		else return x.v < y.v;
	}
}a[MAXN];
struct Node{
	int maxx, tag;
}t[MAXN << 2];
inline void push_up(int x){
	t[x].maxx = max(t[x << 1].maxx, t[x << 1 | 1].maxx);
	return;
}
inline void build(int x, int l, int r){
	if(l == r){
		t[x].tag = t[x].maxx = 0;
		return;
	}
	int mid = (l + r ) >> 1;
	build(x<<1, l, mid);
	build(x<<1|1, mid + 1, r);
	push_up(x);
	return;
}
inline void f(int x, int l, int r, int k){
	t[x].maxx += k;
	t[x].tag += k;
}
inline void push_down(int x, int l, int r){
	if(t[x].tag){
		int mid = (l + r) >> 1;
		f(x << 1, l, mid, t[x].tag);
		f(x << 1 | 1, mid + 1, r, t[x].tag);
		t[x].tag = 0;
	}
}
inline void update(int x, int l, int r, int ll, int rr, int k){
	if(ll <= l && r <= rr){
		f(x, l, r, k);
		return;
	}
	push_down(x, l, r);
	int mid = (l + r) >> 1;
	if(ll <= mid) update(x << 1, l, mid, ll, rr, k);
	if(mid < rr) update(x << 1 | 1, mid + 1, r, ll, rr, k);
	push_up(x);
	return;
}
inline int query(int x, int l, int r, int ll, int rr){
	if(ll <= l && r <= rr) return max(0, t[x].maxx);
	push_down(x, l, r);
	int mid = (l + r) >> 1, maxx = 0;
	if(ll <= mid) maxx = max(maxx, query(x << 1, l, mid, ll, rr));
	if(mid < rr) maxx =  max(maxx, query(x << 1 | 1, mid + 1, r, ll, rr));
	return maxx;
}
int main(){
	#ifndef ONLINE_JUDGE
	freopen("ce.in", "r", stdin);
	#endif
	scanf("%d", &n);
	int cura, curb, curc, curd;
	for(int i = 1; i <= n; i++){
		scanf("%d%d%d%d", &cura, &curb, &curc, &curd);
		curb++;
		a[++cnt] = (Node2){curd, 1, curd, curb};
		a[++cnt] = (Node2){curb, -1, curd, curb};
	}
	for(int i = 1; i <= cnt; i++) pre[i] = a[i].pos;
	sort(&pre[1], &pre[cnt + 1]);
	int ccnt = unique(&pre[1], &pre[cnt + 1]) - 1 - pre;
	n = ccnt;
	for(int i = 1; i <= cnt; i++){
		a[i].pos = lower_bound(&pre[1], &pre[ccnt + 1], a[i].pos) - pre;
		a[i].low = lower_bound(&pre[1], &pre[ccnt + 1], a[i].low) - pre;
		a[i].high = lower_bound(&pre[1], &pre[ccnt + 1], a[i].high) - pre;
	}
	sort(&a[1], &a[cnt + 1]);
	int pre_sum = 0, ans = 0;
	build(1, 1, n);
	for(int i = 1; i <= cnt; i++){
		pre_sum += a[i].v;
		ans = max(ans, pre_sum + query(1, 1, n, 1, n));
		if(a[i].v == -1){
			update(1, 1, n, a[i].low, a[i].high - 1, 1);
		}
	}
	printf("%d\n", ans);
	return 0;
}

B- Cosmetic Survey

#include<bits/stdc++.h>
using namespace std;
const int INF=1e9+7;
int n,m;
int a[505],d[505][505];
vector<int> v;
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		for(int j=1;j<=n;j++)
		{
			scanf("%d",&a[j]);
			if(!a[j]) a[j]=INF;
		}
		for(int j=1;j<=n;j++)
		{
			for(int k=1;k<j;k++)
			{
				if(a[j]<a[k]) d[j][k]++;
				else if(a[j]>a[k]) d[k][j]++;
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<i;j++)
		{
			if(d[i][j]>d[j][i]) d[j][i]=0;
			else if(d[i][j]<d[j][i]) d[i][j]=0;
			else d[i][j]=d[j][i]=0;
			//if(d[i][j]) printf("%d->%d %d\n",i,j,d[i][j]);
			//if(d[j][i]) printf("%d->%d %d\n",j,i,d[j][i]);
		}
	}
	for(int k=1;k<=n;k++)
	{
		for(int i=1;i<=n;i++)
		{
			if(i==k) continue;
			for(int j=1;j<=n;j++)
			{
				if(j==i||j==k||!d[i][k]||!d[k][j]) continue;
				if(!d[i][j]) d[i][j]=min(d[i][k],d[k][j]);
				else d[i][j]=max(d[i][j],min(d[i][k],d[k][j]));
				//printf("d(%d,%d)=%d\n",i,j,d[i][j]);
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		int flag=1;
		for(int j=1;j<=n;j++)
		{
			if(d[i][j]<d[j][i])
			{
				flag=0;
				break;
			}  
		}
		if(flag) v.push_back(i);
	}
	for(int i=0;i<v.size();i++)
	{
		if(i==v.size()-1) printf("%d\n",v[i]);
		else printf("%d ",v[i]);
	}
	return 0;
}

C- Disks Arrangement

D- Go Latin

签到题qwq

#include<bits/stdc++.h>
#define MAXN 100010
using namespace std;
int T, n;
char a[MAXN];
int main(){
	#ifndef ONLINE_JUDGE
	freopen("ce.in", "r", stdin);
	#endif
	scanf("%d", &T);
	while(T--){
		scanf("%s", a + 1); 
		n = strlen(a + 1);
		if(a[n] == 'a' || a[n] == 'o' || a[n] == 'u') a[++n] = 's';
		else if(a[n] == 'i' || a[n] == 'y') a[n] = 'i', a[++n] = 'o', a[++n] = 's';
		else if(a[n] == 'l') a[++n] = 'e', a[++n] = 's';
		else if(a[n] == 'n') a[n] = 'a', a[++n] = 'n', a[++n] = 'e', a[++n] = 's';
		else if(a[n - 1] == 'n' && a[n] == 'e')
			a[n - 1] = 'a', a[n] = 'n', a[++n] = 'e', a[++n] = 's';
		else if(a[n] == 'r' || a[n] == 'v')
			a[++n] = 'e', a[++n] = 's';
		else if(a[n] == 't' || a[n] == 'w')
			a[++n] = 'a', a[++n] = 's';	
		else a[++n] = 'u', a[++n] = 's';
		for(int i = 1; i <= n; i++) printf("%c", a[i]); puts("");
	}
	return 0;
}

E- LED

#include <bits/stdc++.h>
using namespace std;
#define maxn 1000000
#define INF 1000000000
#define eps 0.0001
#define db double
int n;
db preRec[maxn], postRec[maxn];

struct node {
	int x; db y;
	friend bool operator <(node a, node b) {
		return a.x < b.x;
	}
}P[maxn];

bool Check(db mid) {
	int p = 1;
	for(; p <= n; p ++)
		if(P[p].y > mid) break;
	if(p > n) return 1;
	db minx = INF, maxx = -INF; int p1 = 0;
	for(int i = p; i <= n; i ++) {
		db minx1 = min(P[i].y, minx), maxx1 = max(maxx, P[i].y);
		if((maxx1 - minx1) / 2 <= mid) {
			maxx = maxx1, minx = minx1;
			preRec[i] = max((db) 0, maxx - mid); p1 = i;
		//	cout << "what?? " << maxx << " " << minx << " " << p1 << " " << i << " " << preRec[i] << endl;
		}
		else break;
	}
	//cout << "$$%%$" << mid << " " << maxx << " " << minx << " " << p1 << " " << << endl;
	if(p1 == n) return 1;
	minx = INF, maxx = -INF; int p2 = 0;
	for(int i = n; i > p; i --) {
		db minx1 = min(P[i].y, minx), maxx1 = max(maxx, P[i].y);
		if((maxx1 - minx1) / 2 <= mid) {
			maxx = maxx1, minx = minx1;
			postRec[i - 1] = minx + mid; p2 = i - 1;
		}
		else break;
	}
//	cout << "$$$" << mid << " " << p2 << " " << p1 << " " << preRec[p1] << " " << postRec[p1] << endl;
	for(int i = p2; i <= p1; i ++)
		if(preRec[i] <= postRec[i]) return 1;
	return 0;
}

int main() {
	ios::sync_with_stdio(0); cin.tie(0);
	cin >> n;
	db r = 0;
	for(int i = 1; i <= n; i ++) {
		cin >> P[i].x >> P[i].y;
		r = max(r, P[i].y);
	}
	sort(P + 1, P + 1 + n);
	db l = 0;
	if(P[1].x == 0) l = P[1].y;
	//Check(1);
	while(r - l > eps) {
		db mid = (l + r) / 2;
		if(Check(mid)) r = mid;
		else l = mid;
	//	cout << "???" << l << " " << r << endl;
	}
	cout << fixed << setprecision(1) << l << endl;
	return 0;
}

F- Parentheses

暴力模拟qwq?
我又不知道自己哪里写错了QAQ

#include<bits/stdc++.h>
#define MAXN 100010
using namespace std;
int n, T;
int l[MAXN], r[MAXN];
char s[MAXN], ss[MAXN];
inline bool is_char(char x){
	if('a' <= x && x <= 'z') return true;
	else return false;
}
inline bool is_op(char x){
	if(x == '+' || x == '-' || x == '*' || x == '/' || x == '%') return true;
	else return false;
}
inline void check(){
	s[0] = '(';
	s[++n] = ')';
	int top = 0, cnt_char = 0, cnt_op = 0, cnt_pa = 0;
//	printf("%s", s); puts("");
	int st[MAXN];
	for(int i = 0; i <= n; i++){
		if(s[i] == '(') st[++top] = i, cnt_pa++;
		else if(s[i] == ')'){
			r[st[top]] = i;
			l[i] = st[top];
			top--;
		}
		else if(is_char(s[i])) cnt_char++;
		else if(is_op(s[i])) cnt_op++;
	}
	if(cnt_char - cnt_op != 1 || top != 0){
		printf("error\n");
		return;
	}
	for(int i = 0; i <= n; i++){
		if(r[i] == r[i + 1] - 1 || r[i] == i + 2){
			printf("improper\n");
			return;
		}
	}
	if(cnt_pa != cnt_char - 1) printf("improper\n");
	else printf("proper\n");
}
int main(){
	#ifndef ONLINE_JUDGE
	freopen("ce.in", "r", stdin);
	#endif
//	scanf("%d", &T);
//	while(T--){
		while(scanf("%s", ss + 1) != EOF){
			for(int i = 1; i <= strlen(ss + 1); i++)
				s[++n] = ss[i];
		}
		check();
//	}
	return 0;
}

这里是可爱队友的AC代码qwq

#include <bits/stdc++.h>
using namespace std;
#define maxn 10000
int top = 0, n;
char s[maxn];
string ts;

struct node {
	int x, y;
	node(int _x = 0, int _y = 0) {
		x = _x, y = _y;
	}
	friend bool operator ==(node a, node b) {
		return (a.x == b.x) && (a.y == b.y);
	}
}; node st[maxn];

int Pre() {
	for(int i = 1; i <= n; i ++) {
		int opt;
		if(s[i] == '+' || s[i] == '-' || s[i] == '/' || s[i] == '*' || s[i] == '%') opt = 2;
		else if(s[i] == '(') opt = 0;
		else if(s[i] == ')') opt = 1;
		else opt = 3;
		//cout << "_________" << s[i] << " " << opt << endl;
		if(opt == 0) {
			if(top && st[top] == node(3, 0)) return -1;
			st[++ top] = node(0, 0);
		}
		else if(opt == 1) {
			if(top < 2) return -1;
		//	cout << "QAQ" << st[top].x << " " << st[top].y << " " << st[top - 1].x << " " << st[top - 1].y << endl;
			if(st[top] == node(3, 0) && st[top - 1] == node(0, 0)) 
				top -= 1, st[top] = node(3, 0);
			else return -1;
		}
		else if(opt == 2){
			if(top && st[top] == node(3, 0)) st[top] = node(3, -1);
			else return -1; 
		}
		else if(opt == 3) {
			if(!top || st[top] == node(0, 0)) st[++ top] = node(3, 0);
			else if(st[top] == node(3, 0)) return -1;
			else if(st[top] == node(3, -1)) st[top] = node(3, 0);
		}
		while(top >= 1 && st[top] == node(3, 0)) {
			if(st[top - 1] == node(3, -1)) top -= 1, st[top] = node(3, 0);
			else break;
		}
	//	if(top) cout << "???" << s[i] << " " << st[top].x << " " << st[top].y << " " << top << " " << opt << endl;
	}
	if(top > 1) return -1;
	if(!(st[top] == node(3, 0))) return -1;
	return 1;
}

int Work() {
	top = 0;
	for(int i = 1; i <= n; i ++) {
		int opt;
		if(s[i] == '+' || s[i] == '-' || s[i] == '/' || s[i] == '*' || s[i] == '%') opt = 2;
		else if(s[i] == '(') opt = 0;
		else if(s[i] == ')') opt = 1;
		else opt = 3;
	//	cout << "+++++" << opt << endl;
	//	if(top) cout << "???" << st[top].x << " " << st[top].y << " " << opt << endl;
		if(opt == 0) st[++ top] = node(0, 0); 
		else if(opt == 1) {
			if(top < 2) return -1;
			if(st[top] == node(3, 1) && st[top - 1] == node(0, 0))
				top -= 2, st[++ top] = node(3, 0);
			else return -1;
		}
		else if(opt == 2) {
			if(!top) return -1;
			if(st[top] == node(3, 0)) st[top] = node(3, -1);
			else return -1;
		}
		else {
			if(!top || st[top] == node(0, 0)) st[++ top] = node(3, 0);
			else if(st[top] == node(3, -1)) st[top] = node(3, 1);
			else return -1;
		}
		if(st[top] == node(3, 0) && top >= 2) {
			if(st[top - 1] == node(3, -1)) top --, st[top] = node(3, 1);
		}
	//	if(top) cout << "???" << s[i] << " " << st[top].x << " " << st[top].y << " " << top << " " << opt << endl;
	}
//	cout << "???" << st[top].x << " " << st[top].y << endl;
	if(st[top] == node(3, 1)) return 1;
	else return -1;
}

int main() {
	ios::sync_with_stdio(0); cin.tie(0);
	getline(cin, ts);
	int l = ts.length();
	for(int i = 0; i < l; i ++)
		if(ts[i] != ' ') {
			s[++ n] = ts[i];
		//	cout << s[n];	
		}
//	cout << endl;
	if(n == 1) {
		bool flag = true;
		if(s[1] == '+' || s[1] == '-' || s[1] == '/' || s[1] == '*' || s[1] == '%') flag = 0;
		if(s[1] == '(' || s[1] == ')') flag = 0;
		if(flag) cout << "proper" << endl;
		else cout << "error" << endl;
		return 0;
	}
	if(Pre() == -1) {
		cout << "error" << endl;
		return 0;
	}
	if(Work() == -1) {
	//	cout << "____??" << endl;
		cout << "improper" << endl;
		return 0;
	}
	else cout << "proper" << endl;
	return 0; 
}

G- Secret Code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,head,ab[1005],bc[1005],ca[2005],sa[2005],sb[2005],sc[2005];
int sab[2005],sbc[200],sca[2005];
int s[1005],a[1005],b[1005],c[1005],pre[1005],nxt[1005],f1[2005],f2[2005],s1[2005],s2[2005];
ll calc(int a,int b,int c,int s)
{
	return 1ll*2*s*(a*b+b*c+c*a)-a*b*b-a*c*c-b*a*a-b*c*c-c*a*a-c*b*b;
}
bool cmp(int x,int y)
{
	//int ax=s[y]*(1*a[x]+1*b[x]+1*c[x]),ay=s[x]*(1*a[y]+1*b[y]+1*c[y]);
	ll ax=1ll*s[y]*s[y]*s[y]*calc(a[x],b[x],c[x],s[x]);
	ll ay=1ll*s[x]*s[x]*s[x]*calc(a[y],b[y],c[y],s[y]);
	return ax==ay?x<y:ax<ay;
}
void add(int x,int y)
{
	int p=pre[y];
	if(!p) head=x,pre[y]=x,nxt[x]=y;
	else pre[x]=p,nxt[p]=x,pre[y]=x,nxt[x]=y;
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d%d%d",&s[i],&a[i],&b[i],&c[i]);
		f1[i]=a[i]+b[i],f2[i]=b[i]+c[i];
		sa[i]=s[i]+a[i],sb[i]=s[i]+b[i],sc[i]=s[i]+c[i];
		ab[i]=a[i]+b[i],bc[i]=b[i]+c[i],ca[i]=c[i]+a[i];
		sab[i]=s[i]+ab[i],sbc[i]=s[i]+bc[i],sca[i]=s[i]+ca[i];
		int flag=0;
		for(int j=head;j;j=nxt[j])
		{
			if(cmp(i,j))
			{
				add(i,j);
				flag=1;
				break;
			}
		}
		if(!flag) add(i,0);
	}
	for(int i=head;i;i=nxt[i])
	{
		if(nxt[i]) printf("%d ",i);
		else printf("%d\n",i);
	}
	return 0;
}

H- Simple Polygon

I- Square Root

J- Starwars

K- TV Show Game

#include <bits/stdc++.h>
using namespace std;
#define maxn 1000000
int n, m, K, num[maxn];
int dfn[maxn], low[maxn], timer, tot, top, S[maxn], mark[maxn];
int pos[4]; char c[4];

struct edge {
	int cnp = 1, last[maxn], head[maxn], to[maxn];
	void add(int u, int v) {
		to[cnp] = v, last[cnp] = head[u], head[u] = cnp ++;
	}
}E;

void Tarjan(int u) {
	dfn[u] = low[u] = ++ timer; S[++ top] = u, mark[u] = 1;
	for(int i = E.head[u]; i; i = E.last[i]) {
		int v = E.to[i];
		if(!dfn[v]) Tarjan(v), low[u] = min(low[u], low[v]);
		else if(mark[v]) low[u] = min(low[u], dfn[v]);
	}
	if(low[u] == dfn[u]) {
		int t = -1; ++ tot;
		//cout << "________" << u << endl;
		while(t != u) {
			t = S[top --];
			num[t] = tot;
		//	cout << "* " << tot << " " << t << endl;
 			mark[t] = 0;
		}
	}
}

int main() {
	cin >> K >> n;
	for(int i = 1; i <= n; i ++) {
		for(int j = 1; j <= 3; j ++) {
			cin >> pos[j] >> c[j];
		}
		for(int j = 1; j <= 3; j ++) {
			int x = pos[j]; if(c[j] == 'R') x += K;
			for(int k = 1; k <= 3; k ++) {
				if(k == j) continue;
				int y = pos[k]; if(c[k] == 'B') y += K;
			//	cout << "^^^" << x << " " << y << endl;
				E.add(x, y);
			}
		}
	}
	for(int i = 1; i <= 2 * K; i ++)
		if(!dfn[i]) Tarjan(i);
	for(int i = 1; i <= K; i ++) 
		if(num[i] == num[i + K]) {
			cout << "-1" << endl;
			return 0;
		}
	for(int i = 1; i <= K; i ++) {
		if(num[i] < num[i + K]) cout << "R";
		else cout << "B";
	}
	cout << endl;
}

L- Working Plan

#include<bits/stdc++.h>
using namespace std;
int n,m,w,h;
int wl[2005],nd[2005],cnt[2005];
priority_queue<pair<int,int> > pq;
vector<int> v[2005],ans[2005];
int main()
{
	scanf("%d%d%d%d",&n,&m,&w,&h);
	for(int i=1;i<=n;i++) scanf("%d",&wl[i]);
	for(int i=1;i<=m;i++) scanf("%d",&nd[i]);
	for(int i=1;i<=n;i++) pq.push(make_pair(wl[i],i));
	for(int i=1;i<=m;i++)
	{
		if(cnt[i]>nd[i])
		{
			puts("-1");
			return 0;
		}
		while(cnt[i]<nd[i])
		{
			if(pq.empty())
			{
				puts("-1");
				return 0;
			}
			int x=pq.top().second;
			pq.pop();
			if(wl[x]<w)
			{
				puts("-1");
				return 0;
			}
			wl[x]-=w;
			for(int j=i;j<i+w;j++) cnt[j]++;
			if(wl[x]&&i+w+h-1<=m) v[i+w+h-1].push_back(x);
			ans[x].push_back(i);
		}
		for(int j=0;j<v[i].size();j++)
		{
			int x=v[i][j];
			pq.push(make_pair(wl[x],x));
		}
	}
	puts("1");
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<ans[i].size();j++)
		{
			if(j==ans[i].size()-1) printf("%d\n",ans[i][j]);
			else printf("%d ",ans[i][j]);
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值