2018 ICPC Asia Jakarta Regional Contest 9/12

A

Solved: 00:34 BPM136
对于0的个数和1的个数不相等直接输出0或1,否则输出10000…/01111…

#include 

using namespace std;

int main() {
	string s;
	cin >> s;
	int num0 = 0, num1 = 0;
	for (auto c : s) 
		if (c == '0')
			++num0;
		else
			++num1;
	if (num0 == num1) {
		int t = s[0] - '0';
		cout << 1 - t;
		for (int i = 1; i < s.size(); ++i)
			cout << t;
		cout << '\n';
	} else {
		int t = num0 > num1 ? 1 : 0;
		for (int i = 0; i < s.size(); ++i)
			cout << t;
		cout << '\n';
	}
}

B

Unsolved

C

Unsolved
对于N小的时候跑欧拉路径,对于N大的时候直接随机(未补)

D

Solved: 00:35 zkp

#include 
using namespace std;
char a[510][510];
int main()
{
	int n,m,ans=0;
	bool w=false;
	cin>>n>>m; 
	for(int i=0;i<n;i++)cin>>a[i];
	for(int i=1;i<n-1;i++)for(int j=1;j<m-1;j++)if(a[i][j]!='#')ans++;
	for(int i=1;i<m-1;i++)if(a[0][i]=='#'||a[n-1][i]=='#')w=true;
	for(int i=1;i<n-1;i++)if(a[i][0]=='#'||a[i][m-1]=='#')w=true;
	if(!w)ans++;
	if(m<=2)
	{
		ans=0;
		for(int i=1;i<n-1;i++)if(!(a[i][0]=='#'||a[i][m-1]=='#'))ans++;
	}
	if(n<=2)
	{
		ans=0;
		for(int i=1;i<m-1;i++)if(!(a[0][i]=='#'||a[n-1][i]=='#'))ans++;
	}
	if(n<=2&&m<=2)ans=0;
	cout<<ans<<endl;
	return 0;
}

E

Unsolved

F

Solved: 02:57 BPM136
贪心即可,每次引爆最可怕的

#include 

using namespace std;

#define SZ(x) ((int)(x).size())

using ll = long long;

int const N = 100005;

int a[N], b[N];
int mx[N];
int n;
ll m;

int main() {
	int bal = 0;
	cin >> n >> m;
	ll lst = 0;
	int cansol = 0;
	for (int i = 0; i < n; ++i) {
		cin >> a[i];
		lst += a[i];
		if (lst <= m) 
			++cansol;
	}
	for (int i = 0; i < n; ++i)
		cin >> b[i];

	if (cansol == 0) {
		puts("-1");
		return 0;
	}

	for (int i = cansol - 1; i >= 0; --i)
		mx[i] = max(mx[i + 1], b[i]);

	lst = 0;
	ll lsta = 0;
	vector<ll> ans;
	bool can = 0;
	int p = 0;
	for (int i = 0; i < cansol; ++i) {
LABEL1 :
		lst += b[i];
		if (lst > m) {
			can = 1;
			break;
		}
		while (p < n && lsta + a[p] <= lst) {
			lsta += a[p];
			++p;
			++bal;
		}
		if (bal && mx[i] == b[i]) {
			ans.push_back(lst);
			--bal;
			goto LABEL1;
		}
	}
	if (can) {
		cout << SZ(ans) << '\n';
		for (auto v : ans) 
			cout << v << ' ';
		cout << '\n';
	} else
		puts("-1");
}

G

Solved: 04:08 BPM136
类似拓扑排序乱搞即可,不过好像是 N 3 l o g 2 N N^3 log_2N N3log2N的?
其实可以set维护没有被连接的边,这样就是 N 2 ( l o g 2 N ) 2 N^2(log_2N)^2 N2(log2N)2
但是自己弱写成傻逼最后还是改成了乱搞,然而跑的飞快

#include 

using namespace std;

#define SZ(x) ((int)(x).size())

int const N = 505;

bool ma[N][N];

//set ms[N];

int n, m;

bool a[N][N];

bool check(vector<int> const& d, int lim) {
	vector<int> du = d;
	auto q = queue<pair<int, int>>();
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= n; ++j)
			a[i][j] = ma[i][j];

	for (int i = 1; i <= n; ++i)
		for (int j = i + 1; j <= n; ++j)
			if (a[i][j] == 0 && du[i] + du[j] >= lim) {
				a[i][j] = a[j][i] = 1;
				q.push(make_pair(i, j));
			}

	while (q.empty() == 0) {
		auto p = q.front();
		q.pop();
		auto nowa = p.first;
		auto nowb = p.second;
		++du[nowa];
		++du[nowb];
		for (int i = 1; i <= n; ++i) 
			if (i != nowa && a[nowa][i] == 0 && du[nowa] + du[i] >= lim) {
				q.push(make_pair(nowa, i));
				a[nowa][i] = 1;
				a[i][nowa] = 1;
			}
		for (int i = 1; i <= n; ++i) 
			if (i != nowb && a[nowb][i] == 0 && du[nowb] + du[i] >= lim) {
				q.push(make_pair(nowb, i));
				a[nowb][i] = 1;
				a[i][nowb] = 1;
			}
	}
	for (int i = 1; i <= n; ++i)
		if (du[i] != n - 1)
			return 0;
	return 1;
}
/*
bool check(vector const& d, int lim) {
	vector du = d;
	auto q = queue>();
	set s[N];
	for (int i = 1; i <= n; ++i)
		s[i] = ms[i];
	for (int i = 1; i <= n; ++i)
		for (auto j : s[i]) {
			if (du[i] + du[j] >= lim) {
				q.push(make_pair(i, j));
				s[i].erase(j);
				s[j].erase(i);
			}
		}
		for (int i = 1; i <= n; ++i) {
			cerr << "du : " << d[i] << '\n';
			for (auto v : s[i]) 
				cerr << v << ' ';
			cerr << '\n';
		}

	auto funcmorphic = [&] (auto now) {
		++du[now];
		if (SZ(s[now]) == 0)
			return;
		vector ne;
		for (auto v : s[now]) 
			if (du[now] + du[v] >= lim) {
				q.push(make_pair(now, v));
				// s[now].erase(v);
				ne.push_back(v);
				s[v].erase(now);
			}
		for (auto v : ne)
			s[now].erase(v);
	};

	cerr << '\n' << "LIM : " << lim << '\n'; 
	while (q.empty() == 0) {
		auto p = q.front();
		q.pop();
		auto now = p.first;
		funcmorphic(now);
		now = p.second;
		funcmorphic(now);
		cerr << "E : " << p.first << ' ' << p.second << '\n';
		for (int i = 1; i <= n; ++i) {
			cerr << "du : " << du[i] << '\n';
			for (auto v : s[i]) 
				cerr << v << ' ';
			cerr << '\n';
		}
	}
	for (int i = 1; i <= n; ++i)
		if (du[i] != n - 1)
			return 0;
	return 1;
}
*/


int main() {
	cin >> n >> m;
	for (int i = 1; i <= m; ++i) {
		int x, y;
		cin >> x >> y;
		ma[x][y] = ma[y][x] = 1;
	}

	auto d = vector<int>(n + 1, 0);
	for (int i = 1; i <= n; ++i) 
		for (int j = 1; j <= n; ++j) 
			if (i != j) {
				if (ma[i][j]) {
					++d[i];
					++d[j];
				} else {
					// ms[i].insert(j);
					// ms[j].insert(i);
				}
			}
	for (int i = 1; i <= n; ++i)
		d[i] >>= 1;

	int l = 0, r = n << 1;
	int ans = -1;
	while (l <= r) {
		int mid = (l + r) >> 1;
		if (check(d, mid)) {
			ans = mid;
			l = mid + 1;
		} else
			r = mid - 1;
	}
	cout << ans << '\n';
}

H

Solved: 02:36 HOOCCOOH
贪心

#include 
#include 
#include 
#include 
#include 

struct Contr {
    int l, r;
    int sum;

    friend std::istream &operator>>(std::istream &is, Contr &self) {
        is >> self.l >> self.r >> self.sum;
        --self.l;
        return is;
    }
};

std::optional<std::vector<int>> solve(
    const std::vector<int> &init,
    const std::vector<Contr> &contrs
) {
    struct Limit {
        int m, r;

        bool operator<(const Limit &rhs) const {
            if(m != rhs.m)
                return m > rhs.m; // asc
            return r > rhs.r; // asc
        }
    };

    int n = init.size();
    auto presum = std::vector<int>(n + 1);
    auto prehole = std::vector<int>(n + 1);
    for(int i = 0; i < n; ++i) {
        presum[i + 1] = presum[i] + init[i];
        prehole[i + 1] = prehole[i] + (init[i] != 0);
    }

    auto limits = std::vector<std::vector<Limit>>(n);
    for(auto &c: contrs) {
        int len = c.r - c.l - (prehole[c.r] - prehole[c.l]);
        int sum = c.sum - (presum[c.r] - presum[c.l]);
        // std::cerr << "len=" << len << ", sum=" << sum << "\n";
        if(len < sum)
            return {};
        int m = c.l + (len - sum) / 2;
        // std::cerr << "Lim: [" << c.l << "," << m << "," << c.r << ")\n";
        limits[c.l].push_back({ m, c.r });
    }

    auto v = init;
    std::priority_queue<Limit> q;
    int delta_m = 0;

    for(int i = 0; i < n; ++i) {
        for(auto &lim: limits[i])
            q.push({ lim.m - delta_m, lim.r });

        auto try_set = [&]() {
            while(!q.empty()) {
                auto lim = q.top();
                if(lim.r <= i || lim.r <= lim.m + delta_m)
                    q.pop();
                else
                    return i < lim.m + delta_m;
            }
            return true; // No limit
        };

        if(v[i] == 0) {
            v[i] = (try_set() ? -1 : 1);
            if(v[i] == 1)
                ++delta_m;
        } else // hole, no matter it's -1 or 1
            ++delta_m;
    }

    return v;
}

int main() {
    std::ios::sync_with_stdio(false);

    int n, k;
    std::cin >> n >> k;
    auto init = std::vector<int>(n);
    for(auto &c: init)
        std::cin >> c;
    auto contrs = std::vector<Contr>(k);
    for(auto &contr: contrs)
        std::cin >> contr;

    if(auto ans = solve(init, contrs)) {
        for(auto c: *ans)
            std::cout << c << " ";
        std::cout << "\n";
    } else
        std::cout << "Impossible\n";

    return 0;
}

I

Solved: 00:17 BPM136
简单签到

#include 

using namespace std;

int a[100005];

int main() {
	int n;
	cin >> n;
	string s;
	for (int i = 1; i <= n; ++i) {
		cin >> s;
		if (s == "LIE") 
			a[i] = 0;
		else 
			a[i] = 1;
	}

	int ans = a[n];
	for (int i = n - 1; i >= 1; --i)
		if (ans)
			ans = a[i];
		else
			ans = 1 - a[i];
	if (ans == 0) 
		puts("LIE");
	else 
		puts("TRUTH");
}

J

Solved: 02:07 BPM136
状压,sort后前缀max二分辅助转移
据说直接sort的string复杂度是不对的?毕竟复杂度取决于比较次数,不过好像还是 n l o g n nlogn nlogn级别的?

#include 

using namespace std;

#define SZ(x) ((int)(x).size())
#define ALL(x) (x).begin(), (x).end()

int const N = 17;
int const M = 1 << 16;

string s[N];
int n;

int f[N][M];

struct node {
	int i;
	int st;
	int len;
	int mx;
	bool operator < (node const& b) const {
		int tst1 = st, tst2 = b.st;
		while (tst1 && tst2) {
			int pos1 = __builtin_ffs(tst1) - 1;
			int pos2 = __builtin_ffs(tst2) - 1;
			if (s[i][pos1] < s[b.i][pos2])
				return 1;
			if (s[i][pos1] > s[b.i][pos2])
				return 0;
			tst1 -= 1 << pos1;
			tst2 -= 1 << pos2;
		}
		if (__builtin_popcount(st) < __builtin_popcount(b.st))
			return 1;
		return 0;
	}
};
vector<node> g[N];

int solve(int i, int st) {
	node now = node{ i + 1, st, 0, 0 };
	int l = 0, r = SZ(g[i]) - 1;
	int ret = 0;
	while (l <= r) {
		int mid = (l + r) >> 1;
		if (g[i][mid] < now) {
			ret = max(ret, g[i][mid].mx);
			l = mid + 1;
		} else
			r = mid - 1;
	}
	return ret;
}

int main() {
	cin >> n;
	for (int i = 0; i < n; ++i)
		cin >> s[i];
	string t;
	for (int i = 1, len = 1 << SZ(s[0]); i < len; ++i) {
		f[0][i] = __builtin_popcount(i);
		g[0].push_back(node{ 0, i, f[0][i], 0 });
	}

	sort(ALL(g[0]));
	int mx = 0;
	for (int i = 0; i < SZ(g[0]); ++i) {
		mx = max(mx, g[0][i].len);
		g[0][i].mx = mx;
	}

	for (int i = 1; i < n; ++i) {
		for (int j = 1, len = 1 << SZ(s[i]); j < len; ++j) {
			int cnm = solve(i - 1, j);
			if (cnm == 0)
				continue;
			f[i][j] = max(f[i][j], cnm + __builtin_popcount(j));
			g[i].push_back(node{ i, j, f[i][j], 0 });
		}
		sort(ALL(g[i]));
		mx = 0;
		for (int j = 0; j < SZ(g[i]); ++j) {
			mx = max(mx, g[i][j].len);
			g[i][j].mx = mx;
		}
	}

	int ans = -1;
	for (int i = 1, len = 1 << SZ(s[n - 1]); i < len; ++i)
		if (f[n - 1][i])
			ans = max(ans, f[n - 1][i]);
	cout << ans << '\n';
}

K

Unsolved
dfs
惊了出现了点事故,先算Unsolved

L

Solved: 00:11 BPM136

#include 

using namespace std;

#define SZ(x) ((int) (x).size())

using ll = long long;

bool c[100];

bool judge(string const& s, ll k) {
	string ne;
	for (int i = 0; i < SZ(s); ++i)
		if (c[i] == 0) 
			ne += s[i];

	ll t = 0, cr = 1;
	for (int i = SZ(ne) - 1; i >= 0; --i) {
		if (ne[i] == '1')
			t += cr;
		cr <<= 1;
	}
	if (t <= k)
		return 1;
	else
		return 0;
}

int main() {
	ll k;
	cin >> k;
	string s;
	cin >> s;
	int ans = 0;
	if (judge(s, k) == 0) {
		for (int i = 1; i < SZ(s); ++i) 
			if (s[i] == '1') {
				c[i] = 1;
				++ans;
				if (judge(s, k)) 
					break;
			}
		if (judge(s, k) == 0) {
			for (int i = 1; i < SZ(s); ++i)
				if (c[i] == 0) {
					c[i] = 1;
					++ans;
					if (judge(s, k))
						break;
				}
		}
	}
	cout << ans << '\n';
	return 0;
}

你可能感兴趣的:(ACM补题)