2016CCPC东北地区大学生程序设计竞赛

A

思路:所有点都连接到1点即可

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <bitset>

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define pill pair<int, int>
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 5e5 + 10;
const LL INF = 1e9 + 10;

int main(){
	int t;	scanf("%d", &t);
	int Cas = 0;
	while(t--) {
		int n;	scanf("%d", &n);
		printf("Case #%d: %lld\n", ++Cas, (LL)(2 + n) * (n - 1) / 2);
	}
	return 0;
}


C

思路:队友推了一下发现答案只可能是a b

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <bitset>

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define pill pair<int, int>
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 5e5 + 10;
const LL INF = 1e9 + 10;

int main(){
	int t;	scanf("%d", &t);
	int Cas = 0;
	while(t--) {
		LL a, b;	scanf("%lld%lld", &a, &b);
		printf("Case #%d:\n", ++Cas);
		if(a == b) {
			printf("1\n%lld %lld\n", a, b);
		} else {
			printf("2\n%lld %lld\n%lld %lld\n", a, b, b, a);
		}
	}
	return 0;
}

D

思路:不会离散化二维图,看了某位聚聚的代码,然后自己推敲了一下,发现最后离散化后的图第i行的点都具有相同的i',第j列的点都具有相同的j'

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define mst(a, b) memset(a, b, sizeof a)
#define pb push_back
const int qq = 1000 + 5;
int dir[][4] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int nr, nc, vis[qq][qq], x[qq], y[qq], vx[qq], vy[qq];
LL Dfs(int a, int b) {
	LL ans = (LL)vx[a] * vy[b];
	vis[a][b] = 1;
	for(int i = 0; i < 4; ++i) {
		int xx = a + dir[i][0], yy = b + dir[i][1];
		if(xx < 1 || xx > nr || yy < 1 || yy > nc || vis[xx][yy])	continue;
		ans += Dfs(xx, yy);
	}
	return ans;
}
vector<LL> ans;
int R, C, q, s[qq], pos[qq];

int main() {
	int T;	scanf("%d", &T);
	int Cas = 0;
	while(T--) {
		mst(vis, 0);
		ans.clear();
		scanf("%d%d%d", &R, &C, &q);
		for(int i = 0; i < q; ++i) {
			scanf("%d%d", x + i, y + i);
		}
		int cnt = 0;
		nr = 0;
		s[cnt++] = 0, s[cnt++] = R;
		for(int i = 0; i < q; ++i) {
			s[cnt++] = x[i];
		}
		sort(s, s + cnt);
		cnt = unique(s, s + cnt) - s;
		for(int i = 1; i < cnt; ++i) {
			if(s[i] > s[i - 1] + 1)	vx[++nr] = s[i] - s[i - 1] - 1;
			vx[++nr] = 1;
			pos[i] = nr;
		}
		for(int i = 0; i < q; ++i) {
			int t = lower_bound(s, s + cnt, x[i]) - s;
			x[i] = pos[t];
		}
		cnt = nc = 0;
		s[cnt++] = 0, s[cnt++] = C;
		for(int i = 0; i < q; ++i) {
			s[cnt++] = y[i];
		}
		sort(s, s + cnt);
		cnt = unique(s, s + cnt) - s;
		for(int i = 1; i < cnt; ++i) {
			if(s[i] > s[i - 1] + 1) vy[++nc] = s[i] - s[i - 1] - 1;
			vy[++nc] = 1;
			pos[i] = nc;
		}
		for(int i = 0; i < q; ++i) {
			int t = lower_bound(s, s + cnt, y[i]) - s;
			y[i] = pos[t];
		}
		for(int i = 0; i < q; ++i) {
			vis[x[i]][y[i]] = 1;
		}
//		for(int i = 1; i <= nr; ++i) {
//			for(int j = 1; j <= nc; ++j) {
//				printf("%d ", vis[i][j]);
//			}
//			puts("");
//		}
//		puts("QQQQ");
		for(int i = 1; i <= nr; ++i) {
			for(int j = 1; j <= nc; ++j) {
//				printf("%lld ", (LL)vx[i] * vy[j]);
				if(!vis[i][j])	ans.pb(Dfs(i, j));
			}
//			puts("");
		}
		sort(ans.begin(), ans.end());
		printf("Case #%d:\n%d\n", ++Cas, ans.size());
		if(ans.size() == 0)	printf("0");
		for(int i = 0; i < ans.size(); ++i) {
			if(i)	printf(" ");
			printf("%lld", ans[i]);
		}
		puts("");
	}
	return 0;
}



F

队友写了


思路:可以发现0nand任何数都等于1,所以我们只需要维护距离左右两端最近的0然后判断剩下1的奇偶性就好了

#include<bits/stdc++.h>
using namespace std;
set<int> st;

int main() {
	int t;	scanf("%d", &t);
	int Cas = 0;
	while(t--) {
		st.clear();
		set<int>::iterator it;
		int n;	scanf("%d", &n);
		char op[10];
		int x;
		printf("Case #%d:\n", ++Cas);
		int l = 2e5 + 10, r = 2e5 + 10 - 1;
		int l0 = -1, r0 = -1;
		int f = 0;
		while(n--) {
			scanf("%s", op);
			if(op[0] == 'P') {
				if(op[1] == 'U') {
					scanf("%d", &x);
					if(f == 0) {
						r++;
						if(x == 0) {
							st.insert(r);
							if(l0 == -1 && r0 == -1) {
								l0 = r0 = r;
							} else {
								r0 = r;
							}
						}
					} else {
						l--;
						if(x == 0) {
							st.insert(l);
							if(l0 == -1 && r0 == -1) {
								l0 = r0 = l;
							} else {
								l0 = l;
							}
						}
					}
				} else if(op[1] == 'O'){
					if(f == 0) {
						if(r0 != -1 && r == r0) {
							it = st.end();
							--it;
							st.erase(it);
							if(st.size() == 0) {
								l0 = r0 = -1;
							} else {
								it = st.end();
								--it;
								r0 = *it;
							}
						}
						r--;
					} else if(f == 1){
						if(l0 != -1 && l == l0) {
							it = st.begin();
							st.erase(it);
							if(st.size() == 0) {
								l0 = r0 = -1;
							} else {
								it = st.begin();
								l0 = *it;
							}
						}
						l++;
					}
				}
			} else if(op[0] == 'R') {
				f ^= 1;
			} else if(op[0] == 'Q') {
				if(l > r) {
					printf("Invalid.\n");
				} else if(l0 == -1 && r0 == -1) {
					printf("%d\n", (r - l + 1) % 2 == 0 ? 0 : 1);
				} else if(f == 0) {
					int tot = (r - l0 > 0 ? 1 : 0);
					tot += (l0 - l);
					printf("%d\n", tot % 2 == 0 ? 0 : 1);
				} else if(f == 1) {
					int tot = (r0 - l > 0 ? 1 : 0);
					tot += (r - r0);
					printf("%d\n", tot % 2 == 0 ? 0 : 1);
				}
			}
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值