2014-2015 Northwestern European Regional Contest (NWERC 2014)【solved:7 / 11】
2017-09-04 19:31
981 查看
说实话 我觉得k是还能抢救一下的那种
update:2017年10月17日22:48:45
思路:简单dp。注意切d刀是d+1段。
思路:显然若它的初始态为L,则它向右儿子提供的改变状态次数将是它的状态次数/2,左儿子是上取整。所以这其实是一个DAG,每个顶点在入度为0的时候才计算它的终止态翻转多少次,所以使用一个拓扑排序即可。
思路:求个导,发现单调,二分一下就行。
思路:随机得到两个点,构成一条直线,O(n)check是否满足题意,获得正解的概率应该是p2,最低应该是1/25。emmm。可我不知道为什么要随机这么多次才能过….
思路:题意杀….懂题意就很好写了啊。。
http://blog.csdn.net/qq_29556211/article/details/78267854
update:2017年10月17日22:48:45
C - Cent Savings (DP)
题意:让你分d次,问你一个序列被分成d+1段后,每段内部加和,四舍五入,然后统计所有段的加和的最小值是多少。n≤2000,d≤20。思路:简单dp。注意切d刀是d+1段。
#include <bits/stdc++.h> using namespace std; const int maxn = 2000 + 5; const int INF = 0x3f3f3f3f; int a[maxn], sum[maxn], dp[maxn][25]; int calc(int lb, int rb) { int temp = sum[rb] - sum[lb - 1]; return (temp + 5) / 10 * 10; } int main() { int n, d; scanf("%d%d", &n, &d); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); sum[i] 4000 = sum[i - 1] + a[i]; } memset(dp, INF, sizeof(dp)); for(int i = 1; i <= n; i++) dp[i][1] = calc(1, i); for(int i = 1; i <= n; i++) { for(int j = 2; j <= d + 1; j++) { for(int k = 1; k < i; k++) { dp[i][j] = min(dp[i][j], dp[k][j - 1] + calc(k + 1, i)); } } } int ans = calc(1, n); for(int i = 1; i <= d + 1; i++) ans = min(ans, dp [i]); printf("%d\n", ans); return 0; }
D - Digi Comp II (DAG)
题意:给你一张有向图,有m个顶点有左右两条有向边(m≤5e5),每个顶点有个初始状态L/R,每当有一个小球从顶点1落下,他将通过经过的顶点的状态决定前进方向,并改变这些顶点的状态。思路:显然若它的初始态为L,则它向右儿子提供的改变状态次数将是它的状态次数/2,左儿子是上取整。所以这其实是一个DAG,每个顶点在入度为0的时候才计算它的终止态翻转多少次,所以使用一个拓扑排序即可。
#include <bits/stdc++.h> using namespace std; const int maxn = 500000 + 5; vector<int>G[maxn]; int in[maxn]; char state[maxn]; long long dp[maxn]; int main() { long long n, m; scanf("%I64d%I64d", &n, &m); for(int i = 1; i <= m; i++) dp[i] = in[i] = 0; for(int i = 1; i <= m; i++) { char ch; int x, y; getchar(); scanf("%c%d%d", &state[i], &x, &y); G[i].push_back(x); G[i].push_back(y); in[x]++, in[y]++; } queue<int>que; for(int i = 1; i <= m; i++) if(in[i] == 0) que.push(i); dp[1] = n; while(que.size()) { int cur = que.front();que.pop(); int lson = G[cur][0], rson = G[cur][1]; if(state[cur] == 'L') { if(lson) dp[lson] += dp[cur] - dp[cur] / 2; if(rson) dp[rson] += dp[cur] / 2; } else if(state[cur] == 'R') { if(rson) dp[rson] += dp[cur] - dp[cur] / 2; if(lson) dp[lson] += dp[cur] / 2; } in[lson]--, in[rson]--; if(lson != 0 && in[lson] == 0) que.push(lson); if(rson != 0 && in[rson] == 0 && lson != rson) que.push(rson); } for(int i = 1; i <= m; i++) { if(dp[i] % 2 == 0 && state[i] == 'L') putchar('L'); else if(dp[i] % 2 == 1 && state[i] == 'L') putchar('R'); else if(dp[i] % 2 == 0 && state[i] == 'R') putchar('R'); else if(dp[i] % 2 == 1 && state[i] == 'R') putchar('L'); } puts(""); return 0; }
E - Euclidean TSP (二分)
题意:给你个函数,仅有一个未知参数C,问你这个C取何值的时候,函数值最小。输出函数值和C。思路:求个导,发现单调,二分一下就行。
#include <bits/stdc++.h> using namespace std; double n, p, s, v; const double sqrt2 = sqrt(2); double f(double c) { return -1.0 * s / v / c / c + n * sqrt2 * ( pow(log2(n), (c * sqrt2))) * log(log2(n)) / (p * 1e9); } double getAns(double c) { return 1.0 * s / v * (1.0 + 1.0 / c) + n * (pow(log2(n), sqrt2 * c)) / (p * 1e9); } int main() { cin >> n >> p >> s >> v; double temp; double lb = 0, rb = 1e9; for(int i = 0; i < 200; i++) { double mid = (lb + rb) / 2; if(f(mid) > 0) rb = mid; else lb = mid; } double c = rb; printf("%.10f %.10f\n", getAns(c), c); return 0; }
F - Finding Lines (随机算法)
题意:二维平面上有n个点(n≤1e5),问你能否找到一条直线,使得有至少p%的点在这条直线上。思路:随机得到两个点,构成一条直线,O(n)check是否满足题意,获得正解的概率应该是p2,最低应该是1/25。emmm。可我不知道为什么要随机这么多次才能过….
#include <bits/stdc++.h> using namespace std; typedef long long LL; using namespace std; const int maxn = 1e5 + 5; const int repeatTimes = 300; pair<int, int>nodes[maxn]; double x1, x2, y1, y2; bool judge(double fx, double fy) { if(fabs(1.0 * (y1 - y2) / (x1 - x2) * (fx - x1) + y1 - fy) < 1e-8) return true; return false; } int main() { int n, p; scanf("%d%d", &n, &p); int limit = (p * n + 99) / 100; for(int i = 1, x, y; i <= n; i++) scanf("%d%d", &x, &y), nodes[i] = {x, y}; for(int k = 1; k <= repeatTimes; k++) { x1 = nodes[1].first, y1 = nodes[1].second; x2 = nodes[2].first, y2 = nodes[2].second; int cnt = 2; for(int i = 3; i <= n; i++) { if(x1 == x2 && nodes[i].first == x1) cnt++; else if(y1 == y2 && nodes[i].second == y1) cnt++; else if(judge(nodes[i].first, nodes[i].second)) cnt++; } if(cnt >= limit) { puts("possible"); return 0; } random_shuffle(nodes + 1, nodes + n); } puts("impossible"); return 0; }
H - Hyacinth (构造)
题意:给你一棵树,每个树有两个频道,相邻结点至少有一个频道相同,使得相邻结点的相同的频道的集合尽量的大。输出方案。第一个样例的集合大小为2,第二个样例大小的集合大小为6。思路:题意杀….懂题意就很好写了啊。。
#include <bits/stdc++.h> using namespace std; const int maxn = 10000 + 5; pair<int, int>ans[maxn]; vector<int>G[maxn]; int cnt, vis[maxn]; void dfs(int cur, int fa, int v1, int v2) { int siz = G[cur].size(), sons = 0; ans[cur] = {v1, v2}; for(int i = 0; i < siz; i++) { int to = G[cur][i]; if(to == fa) continue; sons++; if(G[to].size() == 1) vis[v1] = vis[v2] = 1, dfs(to, cur, v1, v2); else if(vis[v1] == 0) vis[v1] = 1, dfs(to, cur, v1, cnt++); else vis[v2] = 1, dfs(to, cur, v2, cnt++); } } int main() { int n; scanf("%d", &n); for(int i = 0; i < n - 1; i++) { int x, y; scanf("%d%d", &x, &y); G[x].push_back(y); G[y].push_back(x); } cnt = 3; dfs(1, -1, 1, 2); ans[1] = {1, 2}; for(int i = 1; i <= n; i++) printf("%d %d\n", ans[i].first, ans[i].second); return 0; }
I - Indoorienteering (折半搜索)
题意:给一个n*n的邻接矩阵 代表 俩俩顶点之间的距离。一共n个点。然后问你。长度为w的回路是否存在,就是从u出发,最多每条边只能过一次最终回到u。(1\len,w≤1e15)http://blog.csdn.net/qq_29556211/article/details/78267854
J - Judging Troubles (water)
….不小心数组开小了。#include <bits/stdc++.h> using namespace std; const int maxn = 2e5 + 5; int a[maxn], b[maxn]; map<string , int>ma; int main() { int n; scanf("%d", &n); int cnt = 1; char ss[100]; for(int i = 0; i < n; i++) { scanf("%s", ss); string s = ss; if(ma[s] == 0) ma[s] = cnt++; a[ma[s]]++; } for(int i = 0; i < n; i++) { scanf("%s", ss); string s = ss; if(ma[s] == 0) ma[s] = cnt++; b[ma[s]]++; } int ans = 0; for(int i = 1; i < cnt; i++) ans += min(a[i], b[i]); printf("%d\n", ans); return 0; }
相关文章推荐
- 2015-2016 Northwestern European Regional Contest (NWERC 2015) 7/11 待补
- 2012-2013 Northwestern European Regional Contest (NWERC 2012)【solved:6 / 11】
- E - Elementary Math 2015-2016 Northwestern European Regional Contest (NWERC 2015)
- codeforces Gym - 101485 D Debugging (2015-2016 Northwestern European Regional Contest (NWERC 2015))
- I - Identifying Map Tiles 2015-2016 Northwestern European Regional Contest (NWERC 2015)
- codeforces Gym - 101485 A (2015-2016 Northwestern European Regional Contest (NWERC 2015))
- J - Jumbled Communication 2015-2016 Northwestern European Regional Contest (NWERC 2015)
- 2015-2016 Northwestern European Regional Contest (NWERC 2015) E. Elementary Math
- D - Debugging 2015-2016 Northwestern European Regional Contest (NWERC 2015)
- C-Cleaning Pipes(判断两线段相交+二分图判定) 2015-2016 Northwestern European Regional Contest (NWERC 2015)
- 2015-2016 Northwestern European Regional Contest (NWERC 2015) E
- 2015-2016 Northwestern European Regional Contest (NWERC 2015) 补题
- 2015-2016 Northwestern European Regional Contest (NWERC 2015)
- 2013-2014 Northwestern European Regional Contest (NWERC 2013)
- Codeforces-20152016-northwestern-european-regional-contest-nwerc-A题
- 2015-2016 Northwestern European Regional Contest 训练总结 【5+2】【待补】
- A - Assigning Workstations 2015-2016 Northwestern European Regional Contest
- 2014-2015 ACM-ICPC Northeastern European Regional Contest (NEERC 14)
- 2015-2016 Northwestern European Regional Contest I.Identifying Map Tiles(超级技巧+脑洞)
- 2017-2018 Northwestern European Regional Contest (NWERC 2017)