2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) Solution
A:Exam
Solved.
温暖的签。
- #include<bits/stdc++.h>
- using namespace std;
- const int maxn = 1e3 + ;
- int k;
- char str1[maxn], str2[maxn];
- int main()
- {
- while(~scanf("%d",&k))
- {
- scanf("%s", str1 + );
- scanf("%s", str2 + );
- int cnt1 = , cnt2 = ;
- int len = strlen(str1 + );
- for(int i = ; i <= len; ++i)
- {
- if(str1[i] == str2[i]) cnt1++;
- else cnt2++;
- }
- int ans = ;
- if(cnt1 >= k)
- {
- ans = k + cnt2;
- }
- else
- {
- ans = len - (k - cnt1);
- }
- printf("%d\n", ans);
- }
- return ;
- }
B:Coprime Integers
Solved.
枚举gcd反演
- #include<bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- const int maxn = 1e7 + ;
- bool check[maxn];
- int prime[maxn];
- ll mu[maxn];
- void Moblus()
- {
- memset(check, false, sizeof check);
- mu[] = ;
- int tot = ;
- for(int i = ; i < maxn; ++i)
- {
- if(!check[i])
- {
- prime[tot++] = i;
- mu[i] = -;
- }
- for(int j = ; j < tot; ++j)
- {
- if(i * prime[j] > maxn) break;
- check[i * prime[j]] = true;
- if(i % prime[j] == )
- {
- mu[i * prime[j]] = ;
- break;
- }
- else
- {
- mu[i * prime[j]] = -mu[i];
- }
- }
- }
- }
- ll sum[maxn];
- ll calc(int n, int m)
- {
- ll ans = ;
- if(n > m) swap(n, m);
- for(int i = , la = ; i <= n; i = la + )
- {
- la = min(n / (n / i), m / (m / i));
- ans += (ll)(sum[la] - sum[i - ]) * (n / i) * (m / i);
- }
- return ans;
- }
- ll a, b, c, d;
- int main()
- {
- Moblus();
- for(int i = ; i < maxn; ++i) sum[i] = sum[i - ] + mu[i];
- while(~scanf("%lld %lld %lld %lld", &a, &b, &c, &d))
- {
- ll ans = calc(b, d) - calc(a - , d) - calc(b, c - ) + calc(a - , c - );
- printf("%lld\n", ans);
- }
- return ;
- }
C:Contest Setting
Solved.
题意:
有n个题目,每个题目的难度值不同,要选出k个组成一套$Contest$
要求每个题目难度不同,求方案数
思路:
$把难度值相同的题目放在一起作为一种 dp[i][j] 表示选到第i种题目,已经选了k种的方案数$
$然后做01背包即可,注意加上的值为cnt[i] 表示该种题目有多少个$
- #include<bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- const ll MOD = ;
- const int maxn = 1e3 + ;
- int n, k, pos;
- ll cnt[maxn];
- ll dp[maxn];
- map<int, int>mp;
- int main()
- {
- while(~scanf("%d %d", &n, &k))
- {
- mp.clear();
- pos = ;
- memset(cnt, , sizeof cnt);
- for(int i = ; i <= n; ++i)
- {
- int num;
- scanf("%d", &num);
- if(mp[num] == ) mp[num] = ++pos;
- int id = mp[num];
- cnt[id]++;
- }
- memset(dp, , sizeof dp);
- dp[] = ;
- for(int i = ; i <= pos; ++i)
- {
- for(int j = k; j >= ; --j)
- {
- dp[j] = (dp[j] + dp[j - ] * cnt[i] % MOD) % MOD;
- }
- }
- printf("%lld\n", dp[k]);
- }
- return ;
- }
D:Count The Bits
Solved.
题意:
在$[0, 2^b - 1] 中所有k的倍数以二进制形式表示有多少个1$
思路:
$dp[i][j] 表示枚举二进制位数,j 模k的余数, 表示的是前i位中模k的余数为j的数中1的个数$
$cnt[i][j] 表示当前二进制位为第i位, 模k的余数为j的数的个数$
直接转移即可。
- #include<bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- const ll MOD = (ll)1e9 + ;
- const int maxn = 1e3 + ;
- int k, b;
- ll cnt[maxn][maxn];
- ll dp[maxn][maxn];
- int main()
- {
- while(~scanf("%d %d", &k, &b))
- {
- memset(cnt, , sizeof cnt);
- memset(dp, , sizeof dp);
- cnt[][]++;
- cnt[][ % k]++;
- dp[][ % k]++;
- ll tmp = ;
- for(int i = ; i <= b; ++i)
- {
- tmp = (tmp << ) % k;
- for(int j = ; j < k; ++j)
- {
- //
- cnt[i + ][j] = (cnt[i + ][j] + cnt[i][j]) % MOD;
- dp[i + ][j] = (dp[i + ][j] + dp[i][j]) % MOD;
- //
- ll tmp2 = (tmp + j) % k;
- cnt[i + ][tmp2] = (cnt[i + ][tmp2] + cnt[i][j]) % MOD;
- dp[i + ][tmp2] = ((dp[i + ][tmp2] + cnt[i][j]) % MOD + dp[i][j]) % MOD;
- }
- }
- printf("%lld\n", dp[b][]);
- }
- return ;
- }
- #include <bits/stdc++.h>
- using namespace std;
- #define N 1010
- #define ll long long
- const ll MOD = (ll)1e9 + ;
- ll dp[N][N], cnt[N][N];
- int n, k;
- int main()
- {
- while (scanf("%d%d", &k, &n) != EOF)
- {
- memset(dp, , sizeof dp);
- memset(cnt, , sizeof cnt);
- ++dp[][ % k];
- ++cnt[][ % k];
- ++cnt[][];
- ll tmp = % k;
- for (int i = ; i <= n; ++i)
- {
- tmp = tmp * % k;
- for (int j = ; j < k; ++j)
- {
- dp[i][j] = dp[i - ][j];
- cnt[i][j] = cnt[i - ][j];
- if (j - tmp >= )
- {
- dp[i][j] = (dp[i][j] + dp[i - ][j - tmp] + cnt[i - ][j - tmp]) % MOD;
- cnt[i][j] = (cnt[i][j] + cnt[i - ][j - tmp]) % MOD;
- }
- else
- {
- dp[i][j] = (dp[i][j] + dp[i - ][k + j - tmp] + cnt[i - ][k + j - tmp]) % MOD;
- cnt[i][j] = (cnt[i][j] + cnt[i - ][k + j - tmp]) % MOD;
- }
- }
- }
- printf("%lld\n", dp[n][]);
- }
- return ;
- }
E:Cops And Robbers
Solved.
题意:
在一个$n * m 的矩阵中,有些地方可以建墙,但是不同的墙开销不同,求最小开销把劫匪围住$
思路:
拆点最小割,但是是点权,拆点即可。
- #include<bits/stdc++.h>
- using namespace std;
- const int maxn = 4e3 + ;
- const int INF = 0x3f3f3f3f;
- struct Edge{
- int to, flow, nxt;
- Edge(){}
- Edge(int to, int nxt, int flow):to(to), nxt(nxt), flow(flow){}
- }edge[maxn << ];
- int head[maxn], dep[maxn];
- int S,T;
- int N, n, m, tot;
- void Init(int n)
- {
- N = n;
- //memset(head, -1, sizeof head);
- for(int i = ; i < N; ++i) head[i] = -;
- tot = ;
- }
- void addedge(int u, int v, int w, int rw = )
- {
- edge[tot] = Edge(v, head[u], w); head[u] = tot++;
- edge[tot] = Edge(u, head[v], rw); head[v] = tot++;
- }
- bool BFS()
- {
- //memset(dep, -1, sizeof dep);
- for(int i = ; i < N; ++i) dep[i] = -;
- queue<int>q;
- q.push(S);
- dep[S] = ;
- while(!q.empty())
- {
- int u = q.front();
- q.pop();
- for(int i = head[u]; ~i; i = edge[i].nxt)
- {
- if(edge[i].flow && dep[edge[i].to] == -)
- {
- dep[edge[i].to] = dep[u] + ;
- q.push(edge[i].to);
- }
- }
- }
- return dep[T] < ? : ;
- }
- int DFS(int u, int f)
- {
- if(u == T || f == ) return f;
- int w, used = ;
- for(int i = head[u]; ~i; i = edge[i].nxt)
- {
- if(edge[i].flow && dep[edge[i].to] == dep[u] + )
- {
- w = DFS(edge[i].to, min(f - used, edge[i].flow));
- edge[i].flow -= w;
- edge[i ^ ].flow += w;
- used += w;
- if(used == f) return f;
- }
- }
- if(!used) dep[u] = -;
- return used;
- }
- int Dicnic()
- {
- int ans = ;
- while(BFS())
- {
- int tmp = DFS(S, INF);
- if(tmp == INF) return -;
- ans += tmp;
- }
- return ans;
- }
- int c;
- int C[maxn];
- char mp[][];
- int calc(int i, int j)
- {
- return i * + j;
- }
- int main()
- {
- while(~scanf("%d %d %d", &m, &n, &c))
- {
- int base = n * + m + ;
- int x, y;
- Init();
- for(int i = ; i <= n; ++i)
- {
- for(int j = ; j <= m; ++j)
- {
- scanf(" %c", &mp[i][j]);
- if(mp[i][j] == 'B') { x = i, y = j; }
- }
- }
- for(int i = ; i <= c; ++i) scanf("%d", C + i);
- S = , T = calc(x, y);
- for(int i = ; i <= n; ++i)
- {
- addedge(S, calc(i, ), INF);
- addedge(S, calc(i, m), INF);
- }
- for(int i = ; i <= m; ++i)
- {
- addedge(S, calc(, i), INF);
- addedge(S, calc(n, i), INF);
- }
- for(int i = ; i <= n; ++i)
- {
- for(int j = ; j <= m; ++j)
- {
- if(i != n)
- {
- addedge(calc(i, j) + base, calc(i + , j), INF);
- addedge(calc(i + , j) + base, calc(i, j), INF);
- }
- if(j != m)
- {
- addedge(calc(i, j)+ base, calc(i, j + ), INF);
- addedge(calc(i, j + ) + base, calc(i, j), INF);
- }
- }
- }
- for(int i = ; i <= n; ++i)
- {
- for(int j = ; j <= m; ++j)
- {
- if(mp[i][j] >= 'a' && mp[i][j] <= 'z')
- {
- addedge(calc(i, j), calc(i, j) + base, C[mp[i][j] - 'a' + ]);
- }
- else
- {
- addedge(calc(i, j), calc(i, j) + base, INF);
- }
- }
- }
- int ans = Dicnic();
- printf("%d\n", ans);
- }
- return ;
- }
F:Rectangles
Solved.
题意:
二维平面上有一些平行坐标轴的矩形,求有多少区间是被奇数个矩形覆盖。
思路:
扫描线,只是把区间加减换成区间01状态翻转,现场学扫描线可还行..
- #include <bits/stdc++.h>
- using namespace std;
- #define ll long long
- #define N 200010
- #define pii pair <int, int>
- int n, mx, my, bx[N], by[N];
- ll res;
- struct Rec
- {
- int x[], y[];
- void scan()
- {
- for (int i = ; i < ; ++i) scanf("%d%d", x + i, y + i);
- if (x[] > x[]) swap(x[], x[]);
- if (y[] > y[]) swap(y[], y[]);
- bx[++mx] = x[];
- bx[++mx] = x[];
- by[++my] = y[];
- by[++my] = y[];
- }
- }rec[N];
- vector <pii> v[N];
- void Hash()
- {
- sort(bx + , bx + + mx);
- sort(by + , by + + my);
- mx = unique(bx + , bx + + mx) - bx - ;
- my = unique(by + , by + + my) - by - ;
- for (int i = ; i <= n; ++i)
- {
- for (int j = ; j < ; ++j)
- {
- rec[i].x[j] = lower_bound(bx + , bx + + mx, rec[i].x[j]) - bx;
- rec[i].y[j] = lower_bound(by + , by + + my, rec[i].y[j]) - by;
- }
- }
- }
- namespace SEG
- {
- struct node
- {
- ll sum, val;
- int lazy;
- node () {}
- node (ll sum, ll val, int lazy) : sum(sum), val(val), lazy(lazy) {}
- void init() { sum = val = lazy = ; }
- node operator + (const node &other) const { return node(sum + other.sum, val + other.val, ); }
- void Xor() { val = sum - val; lazy ^= ; }
- }a[N << ];
- void build(int id, int l, int r)
- {
- a[id] = node(, , );
- if (l == r)
- {
- a[id].sum = by[l + ] - by[l];
- return;
- }
- int mid = (l + r) >> ;
- build(id << , l, mid);
- build(id << | , mid + , r);
- a[id] = a[id << ] + a[id << | ];
- }
- void pushdown(int id)
- {
- if (!a[id].lazy) return;
- a[id << ].Xor();
- a[id << | ].Xor();
- a[id].lazy = ;
- }
- void update(int id, int l, int r, int ql, int qr)
- {
- if (l >= ql && r <= qr)
- {
- a[id].Xor();
- return;
- }
- int mid = (l + r) >> ;
- pushdown(id);
- if (ql <= mid) update(id << , l, mid, ql, qr);
- if (qr > mid) update(id << | , mid + , r, ql, qr);
- a[id] = a[id << ] + a[id << | ];
- }
- }
- int main()
- {
- while (scanf("%d", &n) != EOF)
- {
- mx = my = ; res = ;
- for (int i = ; i <= * n; ++i) v[i].clear();
- for (int i = ; i <= n; ++i) rec[i].scan(); Hash();
- for (int i = ; i <= n; ++i)
- {
- v[rec[i].x[]].emplace_back(rec[i].y[], rec[i].y[] - );
- v[rec[i].x[]].emplace_back(rec[i].y[], rec[i].y[] - );
- }
- n <<= ;
- SEG::build(, , n);
- for (int i = ; i < mx; ++i)
- {
- for (auto it : v[i]) SEG::update(, , n, it.first, it.second);
- res += (bx[i + ] - bx[i]) * SEG::a[].val;
- }
- printf("%lld\n", res);
- }
- return ;
- }
G:Goat on a Rope
Solved.
签到。
- #include<bits/stdc++.h>
- using namespace std;
- double x, y;
- double xa, xb, ya, yb;
- double calc(double xa, double ya, double xb, double yb)
- {
- return sqrt((xa - xb) * (xa - xb) + (ya - yb) * (ya - yb));
- }
- int main()
- {
- while(~scanf("%lf %lf %lf %lf %lf %lf", &x, &y, &xa, &ya, &xb, &yb))
- {
- double ans = 1e9;
- if(x >= min(xa, xb) && x <= max(xa, xb)) ans = min(ans, min(fabs(y - ya), fabs(y - yb)));
- if(y >= min(ya, yb) && y <= max(ya, yb)) ans = min(ans, min(fabs(x - xa), fabs(x - xb)));
- ans = min(ans, calc(x, y, xa, ya));
- ans = min(ans, calc(x, y, xa, yb));
- ans = min(ans, calc(x, y, xb, ya));
- ans = min(ans, calc(x, y, xb, yb));
- printf("%.3f\n", ans);
- }
- return ;
- }
H:Repeating Goldbachs
Solved.
签到。
- #include<bits/stdc++.h>
- using namespace std;
- const int maxn = 1e6 + ;
- bool isprime[maxn];
- int prime[maxn];
- void Init()
- {
- memset(isprime, true, sizeof isprime);
- isprime[] = isprime[] = false;
- for(int i = ; i < maxn; ++i)
- {
- if(isprime[i])
- {
- prime[++prime[]] = i;
- for(int j = i * ; j < maxn; j += i)
- {
- isprime[j] = false;
- }
- }
- }
- }
- int x;
- int main()
- {
- Init();
- while(~scanf("%d", &x))
- {
- int ans = ;
- while(x >= )
- {
- for(int i = ; i <= prime[]; ++i)
- {
- int tmp = prime[i];
- if(isprime[x - tmp])
- {
- ++ans;
- x = x - tmp - tmp;
- break;
- }
- }
- }
- printf("%d\n", ans);
- }
- return ;
- }
I:Inversions
Unsolved.
题意:
给出一些序列,一些位置上的数字可以在$[1, k]的范围内随便填,求如果填使得整个序列的逆序对个数最多$
J:Time Limits
Solved.
签到。
- #include<bits/stdc++.h>
- using namespace std;
- int n, s;
- int main()
- {
- while(~scanf("%d %d", &n, &s))
- {
- int Max = -;
- for(int i = ; i <= n; ++i)
- {
- int num;
- scanf("%d", &num);
- Max = max(Max, num);
- }
- Max *= s;
- int ans = Max / ;
- if(Max % ) ans++;
- printf("%d\n", ans);
- }
- return ;
- }
K:Knockout
Unsolved.
题意:
给出一个数字,然后两个骰子的点数,每次可以移掉数字当中某几位加起来的和等于两骰子点数之和
那么就可以移掉这几位,知道最后不能移位置,最后剩下的数就是分数
现在给出一中间局面,求移掉哪些,使得最后的分数期望最大以及最小
L:Liars
Solved.
签到。
- #include<bits/stdc++.h>
- using namespace std;
- const int maxn = 1e3 + ;
- int n;
- int cnt[maxn];
- int main()
- {
- while(~scanf("%d", &n))
- {
- memset(cnt, , sizeof cnt);
- for(int i = ; i <= n; ++i)
- {
- int ai, bi;
- scanf("%d %d", &ai, &bi);
- for(int j = ai; j <= bi; ++j)
- {
- cnt[j]++;
- }
- }
- int ans = -;
- for(int i = ; i <= n; ++i)
- {
- if(cnt[i] == i) ans = i;
- }
- printf("%d\n", ans);
- }
- return ;
- }
M:Mobilization
Unsolved.
题意:
$有m种军队,每种军队有h_i 属性 和 p_i属性,以及购买一支军队需要c_i的钱,每种军队可以购买无限支$
$现在你有C个单位的钱,求如何购买军队,使得\sum h_i \cdot \sum p_i 最大$
2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) Solution的更多相关文章
- 2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) Solution
A:Alphabet Solved. 签. #include<bits/stdc++.h> using namespace std; ]; ]; int main(){ scanf(); ...
- 2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) Solution
A - Odd Palindrome 水. #include <bits/stdc++.h> using namespace std; #define N 110 char s[N]; i ...
- 2018 ICPC Pacific Northwest Regional Contest I-Inversions 题解
题目链接: 2018 ICPC Pacific Northwest Regional Contest - I-Inversions 题意 给出一个长度为\(n\)的序列,其中的数字介于0-k之间,为0 ...
- 2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)
2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) 思路: A Exam 思路:水题 代码: #include<bits ...
- Contest Setting 2018 ICPC Pacific Northwest Regional Contest dp
题目:https://vj.69fa.cn/12703be72f729288b4cced17e2501850?v=1552995458 dp这个题目网上说是dp+离散化这个题目要对这些数字先处理然后进 ...
- 2015-2016 ACM-ICPC Pacific Northwest Regional Contest (Div. 2) S Surf
SurfNow that you've come to Florida and taken up surng, you love it! Of course, you've realized that ...
- 2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 2) 题解
[题目链接] A - Alphabet 最长公共子序列.保留最长公共子序列,剩余的删除或者补足即可. #include <bits/stdc++.h> using namespace st ...
- 2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) K Tournament Wins
题目链接:http://codeforces.com/gym/101201 /* * @Author: lyucheng * @Date: 2017-10-22 14:38:52 * @Last Mo ...
- 2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)
A. Odd Palindrome 所有回文子串长度都是奇数等价于不存在长度为$2$的偶回文子串,即相邻两个字符都不同. #include<cstdio> #include<cstr ...
随机推荐
- MySQL 密码设置
如何修改 MySQL 密码: [root@localhost ~]$ mysqladmin -uroot password 'newPass' # 在无密码的情况下设置密码 [root@localho ...
- 如何设置SOLR的高亮 (highlight)?
打开SOLR的核心配置文件: solrconfig.xml 找到 standard request handler 写入以下XML配置代码: <requestHandler name=" ...
- 如何在HTML中播放flash
随着html的风靡,改变了之前前端的许多条条框框,而video的出现使flash仿佛都要退出历史的舞台了,但是h5也会出现以下局限性,比如说,在一些不支持h5的浏览器上,此处省略一万只草泥马..... ...
- c++11——列表初始化
1. 使用列表初始化 在c++98/03中,对象的初始化方法有很多种,例如 int ar[3] = {1,2,3}; int arr[] = {1,2,3}; //普通数组 struct A{ int ...
- LeetCode——Power of Two
Description: Given an integer, write a function to determine if it is a power of two. public class S ...
- 2800 送外卖[状态压缩dp]
2800 送外卖 时间限制: 2 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 有一个送外卖的,他手上有n份订单,他 ...
- 使用springBoot进行快速开发
springBoot项目是spring的一个子项目,使用约定由于配置的思想省去了以往在开发过程中许多的配置工作(其实使用springBoot并不是零配置,只是使用了注解完全省去了XML文件的配置),达 ...
- DES加密解密 Java中运用
DES全称Data Encryption Standard,是一种使用密匙加密的块算法.现在认为是一种不安全的加密算法,因为现在已经有用穷举法攻破DES密码的报道了.尽管如此,该加密算法还是运用非常普 ...
- 三维凸包求内部一点到表面的最近距离(HDU4266)
http://acm.hdu.edu.cn/showproblem.php?pid=4266 The Worm in the Apple Time Limit: 50000/20000 MS (Jav ...
- vue-cli 项目打包异常汇总
1.打包路径错误 npm run build 之后,会发现项目目录下多了 通过 localhost 运行 index.html 会发现空白,仔细一看,是因为引用的资源位置问题 明显这个地方应该是 ./ ...