ICPC North Central NA Contest 2017
C题最后过的,条无限长直线将平面画成若干个区域,相邻的类型不一样(可知只需有两个类型就可染色完毕)。个询问,每次询问两个点所在区域是否是同一个类型。思考之后发现,条直线中使两个点在其同一侧的直线,并不对答案造成影响;故只需统计使两个点在两侧的直线的数量即可。
最后是否是相同的类型只需看上述直线的数量的奇偶性即可。
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<cstring>
#include<stack>
#define mem(ss) memset(ss,0,sizeof(ss))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
#define inf 0x3f3f3f3f
typedef long long ll;
typedef long double ld;
typedef double db;
typedef std::pair<int, int> pii;
typedef std::pair<ll, ll> pll;
const ll mod = 1e9 + 7;
const int N = 4e5 + 10;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }
inline ll read() {
ll x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
ll m_pow(ll x, ll n, ll m) {
ll res = 1;
while (n > 0) {
if (n & 1)
res = (res * x) % m;
x = (x * x) % m;
n >>= 1;
}
return res % m;
}
struct Point {
double x, y;
Point() {}
Point(double _x, double _y) {
x = _x;
y = _y;
}
double operator^(const Point &b) const {
return x * b.y - y * b.x;
}
};
int s, t;
vector<Point> p1, p2;
double x1, y, x2, y2, x3, y3, x4, y4;
inline int check(Point v0, Point v1, Point v2) {
double a = (v0 ^ v1);
double b = (v0 ^ v2);
return (a * b) < 0;
}
int main() {
cin >> s;
for (int i = 0; i < s; i++) {
cin >> x1 >> y >> x2 >> y2;
p1.push_back(Point(x1, y));
p2.push_back(Point(x2, y2));
}
cin >> t;
for (int i = 0; i < t; i++) {
int sum = 0;
cin >> x3 >> y3 >> x4 >> y4;
for (int j = 0; j < s; j++) {
Point v0 = Point(p2[j].x - p1[j].x, p2[j].y - p1[j].y);
Point v1 = Point(x3 - p1[j].x, y3 - p1[j].y);
Point v2 = Point(x4 - p1[j].x, y4 - p1[j].y);
sum += check(v0, v1, v2);
}
if (sum & 1) printf("different\n");
else printf("same\n");
}
return 0;
}
J题
裸最小生成树
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<cstring>
#include<stack>
#define mem(ss) memset(ss,0,sizeof(ss))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
#define inf 0x3f3f3f3f
typedef long long ll;
typedef long double ld;
typedef double db;
typedef std::pair<int, int> pii;
typedef std::pair<ll, ll> pll;
const ll mod = 1e9 + 7;
const int N = 4e5 + 10;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }
inline ll read() {
ll x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
ll m_pow(ll x, ll n, ll m) {
ll res = 1;
while (n > 0) {
if (n & 1)
res = (res * x) % m;
x = (x * x) % m;
n >>= 1;
}
return res % m;
}
struct Edge {
int fm, to, dist;
bool operator<(const Edge &rhs) const {
return dist < rhs.dist;
}
};
vector<Edge> e;
int f[3000], n;
int find(int x) {
if (f[x] != x) f[x] = find(f[x]);
return f[x];
}
void merge(int x, int y) {
int xx = find(x);
int yy = find(y);
f[xx] = yy;
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
int tmp;
scanf("%d", &tmp);
if (i < j) e.push_back(Edge{i, j, tmp});
}
sort(e.begin(), e.end());
for (int i = 1; i <= n; i++) f[i] = i;
int rst = n;
for (auto edge:e)
if (rst > 1) {
int x = edge.fm, y = edge.to;
if (find(x) != find(y)) {
merge(x, y);
rst--;
printf("%d %d\n", x, y);
}
}
return 0;
}
I题
模拟。
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<cstring>
#include<stack>
#define mem(ss) memset(ss,0,sizeof(ss))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
#define inf 0x3f3f3f3f
typedef long long ll;
typedef long double ld;
typedef double db;
typedef std::pair<int, int> pii;
typedef std::pair<ll, ll> pll;
const ll mod = 1e9 + 7;
const int N = 4e5 + 10;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }
inline ll read() {
ll x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
ll m_pow(ll x, ll n, ll m) {
ll res = 1;
while (n > 0) {
if (n & 1)
res = (res * x) % m;
x = (x * x) % m;
n >>= 1;
}
return res % m;
}
int T;
string ap;
int a[127];
double d = acos(-1) / 7;
int main() {
int T;
scanf("%d\n", &T);
while (T--) {
double time = 0;
getline(cin, ap);
rep(i, 0, ap.size() - 1) {
if (ap[i] == ' ') a[i] = 26;
else if (ap[i] == '\'') a[i] = 27;
else a[i] = ap[i] - 'A';
}
for (int i = 1; i < ap.size(); i++) {
time += d * min(abs(a[i] - a[i - 1]), 28 - abs(a[i] - a[i - 1]));
}
printf("%.10lf\n", ap.size() + time);
}
return 0;
}
G题
dfs环的数量,基本功。
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<cstring>
#include<stack>
#define mem(ss) memset(ss,0,sizeof(ss))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
#define inf 0x3f3f3f3f
typedef long long ll;
typedef long double ld;
typedef double db;
typedef std::pair<int, int> pii;
typedef std::pair<ll, ll> pll;
const ll mod = 1e9 + 7;
const int N = 4e5 + 10;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }
inline ll read() {
ll x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
ll m_pow(ll x, ll n, ll m) {
ll res = 1;
while (n > 0) {
if (n & 1)
res = (res * x) % m;
x = (x * x) % m;
n >>= 1;
}
return res % m;
}
const int dx[] = {0, 0, 1, -1, 1, -1, 1, -1};
const int dy[] = {1, -1, 0, 0, -1, 1, 1, -1};
int m, n, mp[127][127] = {0}, vis[127][127] = {0}, cnt = 0;
string liner;
inline void dfs(int x, int y) {
vis[x][y] = 1;
rep(i, 0, 7) {
int tx = x + dx[i];
int ty = y + dy[i];
if (tx > 0 && ty > 0 && tx <= m && ty <= n && mp[tx][ty] && !vis[tx][ty]) {
vis[tx][ty] = 1;
dfs(tx, ty);
}
}
}
int main() {
cin >> m >> n;
rep(i, 1, m) {
cin >> liner;
rep(j, 0, n - 1)if (liner[j] == '#') mp[i][j + 1] = 1;
}
rep(i, 1, m)rep(j, 1, n)if (mp[i][j] && !vis[i][j]) {
++cnt;
dfs(i, j);
}
cout << cnt << endl;
return 0;
}
H题
这题比较有意思,每次操作将序列最后的0变为1,然后这位之后全变为0,直到全为1为止。
二进制进位。
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<cstring>
#include<stack>
#define mem(ss) memset(ss,0,sizeof(ss))
#define rep(d, s, t) for(int d=s;d<=t;d++)
#define rev(d, s, t) for(int d=s;d>=t;d--)
#define inf 0x3f3f3f3f
typedef long long ll;
typedef long double ld;
typedef double db;
typedef std::pair<int, int> pii;
typedef std::pair<ll, ll> pll;
const ll mod = 1e9 + 7;
const int N = 4e5 + 10;
#define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }
inline ll read() {
ll x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
ll m_pow(ll x, ll n, ll m) {
ll res = 1;
while (n > 0) {
if (n & 1)
res = (res * x) % m;
x = (x * x) % m;
n >>= 1;
}
return res % m;
}
ll n, a[100];
char an;
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> an;
if (an == 'Z') a[n - i] = 1;
else a[n - i] = 0;
}
ll p = 1, sum = 0;
for (int i = 0; i < n; i++) {
sum += a[i] * p;
p <<= 1;
}
cout << p - sum - 1 << endl;
return 0;
}
浙公网安备 33010602011771号