ACM-ICPC 2018 南京赛区网络预赛 Solution
A. An Olympian Math Problem
cout << n - 1 << endl;
#include <bits/stdc++.h>
using namespace std; #define ll long long int t;
ll n; inline void Run()
{
scanf("%d", &t);
while (t--)
{
scanf("%lld", &n);
printf("%lld\n", n - );
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run(); return ;
}
B. The writing on the wall
题意:给出n * m的矩形,找出有多少个子矩形不包含黑块
思路:枚举每一个当右下角的情况,那么情况总数就是黑块构成的边界里面的格子数量,优先队列优化
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 100010
#define M 110 int t, n, m, k;
int G[N][M];
int low[M]; struct node
{
ll h, num;
inline node() {}
inline node(ll h, ll num) : h(h), num(num) {}
inline bool operator < (const node &r) const
{
return h < r.h;
}
}; priority_queue <node> q; int main()
{
#ifdef LOCAL_JUDGE
freopen("Text.txt", "r", stdin);
#endif // LOCAL_JUDGE
scanf("%d", &t);
for (int kase = ; kase <= t; ++kase)
{
printf("Case #%d: ", kase);
memset(G, , sizeof G);
memset(low, , sizeof low);
while (!q.empty()) q.pop();
scanf("%d%d%d", &n, &m, &k);
for (int i = , x, y; i <= k; ++i)
{
scanf("%d%d", &x, &y);
G[x][y] = ;
}
ll ans = , sum = ;
for (int i = ; i <= n; ++i)
{
for (int j = ; j <= m; ++j)
{
//if (i % 1000 == 0) cout << i << endl;
if (G[i][j] == )
{
while (!q.empty()) q.pop();
sum = ;
low[j] = i;
continue;
}
if (j == )
{
while (!q.empty()) q.pop();
sum = ;
}
ll H = i - low[j];
ll num = ;
while (!q.empty() && q.top().h > H)
{
num += q.top().num;
sum -= q.top().h * q.top().num;
q.pop();
}
sum += num * H;
ans += sum;
q.emplace(H, num);
}
}
printf("%lld\n", ans);
}
return ;
}
C. GDY
按题意模拟即可,注意细节
#include <bits/stdc++.h>
using namespace std; int Move[] = { , , , , , , , , , , , , , }; struct DT
{
int num[], cnt;
int score;
inline DT()
{
score = ; cnt = ;
memset(num, , sizeof num);
}
inline void Get()
{
for (int i = ; i <= ; ++i)
score += num[i] * i;
}
}arr[]; int t, n, m;
queue <int> q; inline void work()
{
int turn = , pre = -, tot = , nx;
for (int i = ; i < ; ++i) if (arr[].num[Move[i]])
{
pre = Move[i];
--arr[].num[Move[i]];
--arr[].cnt;
break;
}
while (true)
{
turn = turn % n + ;
if (tot == n - )
{
for (int i = turn; i <= n; ++i) if (!q.empty())
{
++arr[i].cnt;
++arr[i].num[q.front()]; q.pop();
}
for (int i = ; i < turn; ++i) if (!q.empty())
{
++arr[i].cnt;
++arr[i].num[q.front()]; q.pop();
}
for (int i = ; i < ; ++i) if (arr[turn].num[Move[i]])
{
--arr[turn].num[Move[i]];
if (--arr[turn].cnt == ) return;
pre = Move[i]; tot = ;
break;
}
}
else if (pre == ) tot++;
else
{
if (pre == ) nx = ;
else nx = pre + ;
if (arr[turn].num[nx])
{
--arr[turn].num[nx];
if (--arr[turn].cnt == ) return;
pre = nx; tot = ;
}
else
{
if (arr[turn].num[])
{
--arr[turn].num[];
if (--arr[turn].cnt == ) return;
pre = ; tot = ;
}
else tot++;
}
}
}
} inline void Run()
{
scanf("%d", &t);
for (int kase = ; kase <= t; ++kase)
{
while (!q.empty()) q.pop();
printf("Case #%d:\n", kase);
scanf("%d%d", &n, &m);
for (int i = , u; i <= m; ++i)
{
scanf("%d", &u);
q.emplace(u);
}
for (int i = ; i <= n; ++i)
{
arr[i] = DT();
for (int j = ; j <= ; ++j)
{
if (!q.empty())
{
arr[i].num[q.front()]++; q.pop();
++arr[i].cnt;
}
}
}
work();
for (int i = ; i <= n; ++i)
{
arr[i].Get();
if (arr[i].score == ) puts("Winner");
else printf("%d\n", arr[i].score);
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}
D. Jerome's House
留坑。
E. AC Challenge
题意:有n道题目,每次提交得到分数$t * a_i + b_i$ 有一些题目的提交必须要某些题目提交之后才能提交,求最后获得的最大分数
思路:记忆化搜索,二进制标记状态 或者 状压DP
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll dp[ << ]; int n; struct node {
ll ai, bi;
int state;
inline node(){}
inline node(ll ai, ll bi, int state):ai(ai),bi(bi), state(state){}
}arr[]; inline ll DFS(int t, int S)
{
if (t > n) return ;
if (dp[S] != -) return dp[S];
ll res = ;
for (int i = ; i < n; ++i)
{
int tmp = << i;
if ((tmp & S) == )
{
if ((S & arr[i].state) != arr[i].state) continue;
res = max(res, t * arr[i].ai + arr[i].bi + DFS(t + , (S | tmp)));
}
}
dp[S] = res;
return res;
} inline void RUN()
{
while (~scanf("%d", &n))
{
memset(dp, -, sizeof dp);
for (int i = ; i < n; ++i)
{
int m;
int S = ;
scanf("%lld %lld %d", &arr[i].ai, &arr[i].bi, &m);
while (m--)
{
int tmp = ;
scanf("%d", &tmp);
S += ( << (tmp - ));
}
arr[i].state = S;
}
ll ans = DFS(, );
printf("%lld\n", ans);
}
} int main()
{
#ifdef LOCAL_JUDGE
freopen("Text.txt", "r", stdin);
#endif // LOCAL_JUDGE RUN(); #ifdef LOCAL_JUDGE
fclose(stdin);
#endif // LOCAL_JUDGE return ;
}
#include <bits/stdc++.h>
using namespace std; #define N (1 << 21)
#define ll long long struct node
{
ll a, b;
int sta;
inline void scan()
{
int tot, k; sta = ;
scanf("%lld%lld%d", &a, &b, &tot);
while (tot--)
{
scanf("%d", &k);
sta |= ( << (k - ));
}
}
}arr[]; int n;
ll dp[N]; inline ll Count(int x)
{
int res = ;
while (x)
{
++res;
x &= (x - );
}
return res;
} inline void Run()
{
while (scanf("%d", &n) != EOF)
{
for (int i = ; i <= n; ++i) arr[i].scan();
memset(dp, -, sizeof dp);
ll ans = ; dp[] = ;
for (int i = ; i < ( << n); ++i)
{
if (dp[i] == -) continue;
for (int j = ; j <= n; ++j)
{
if (!(i & ( << (j - ))) && (i & (arr[j].sta)) == arr[j].sta)
{
int tmp = i | ( << (j - ));
ll t = Count(tmp);
dp[tmp] = max(dp[tmp], dp[i] + arr[j].a * t + arr[j].b);
ans = max(ans, dp[tmp]);
}
}
}
printf("%lld\n", ans);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}
F. An Easy Problem On The Trees
留坑。
G. Lpl and Energy-saving Lamps
题意:有n个房间,每次按顺序换灯泡,一个房间要不所有灯泡都换,要不一个都不换,每个月有固定的新灯泡数,没还完留到下个月,询问第几个月能够换掉几个房间以及剩下的房间数
思路:线段树维护一个最小值,预处理答案
#include <bits/stdc++.h>
using namespace std; #define N 100010
#define INF 0x3f3f3f3f
#define ll long long typedef pair <int, int> pii; int n, m, q, sum;
int arr[N];
pii ans[N]; struct node
{
int l, r, cnt;
int Min, sum;
inline node() {}
inline node(int _l, int _r)
{
l = _l, r = _r;
Min = sum = ;
}
}tree[N << ]; inline void pushup(int id)
{
tree[id].Min = min(tree[id << ].Min, tree[id << | ].Min);
tree[id].sum = tree[id << ].sum + tree[id << | ].sum;
tree[id].cnt = tree[id << ].cnt + tree[id << | ].cnt;
} inline void build(int id, int l, int r)
{
tree[id] = node(l, r);
if (l == r)
{
tree[id].Min = tree[id].sum = arr[l];
tree[id].cnt = ;
return;
}
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
pushup(id);
} int anssum, remind; inline void query(int id)
{
if (tree[id].Min <= remind && tree[id].sum <= remind)
{
anssum += tree[id].cnt;
sum -= tree[id].sum;
remind -= tree[id].sum;
tree[id].Min = INF;
tree[id].sum = ;
tree[id].cnt = ;
return;
}
if (tree[id << ].Min <= remind) query(id << );
if (tree[id << | ].Min <= remind) query(id << | );
pushup(id);
} inline void out(int x)
{
if (x / ) out(x / );
putchar(x % + '');
} inline void Run()
{
while (scanf("%d%d", &n, &m) != EOF)
{
memset(ans, , sizeof ans); sum = ;
for (int i = ; i <= n; ++i) scanf("%d", arr + i), sum += arr[i];
build(, , n); remind = m;
for (int i = ; i <= ; ++i, remind += m)
{
if (sum == )
{
ans[i] = ans[i - ];
continue;
}
anssum = ; query();
ans[i].first = ans[i - ].first + anssum;
ans[i].second = remind;
}
scanf("%d", &q);
for (int i = , x; i <= q; ++i)
{
scanf("%d", &x);
out(ans[x].first); putchar(' ');
out(ans[x].second); putchar('\n');
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}
H. Set
留坑。
I. Skr
留坑。
J. Sum
题意:定义$F[n] = 有多少个n = ab$ a 和 b 都不能是平方数的倍数 1 除外 求 $\sum_{i = 1} ^ {i = n} F[n]$
思路:枚举每个素数,对于拥有不同质因子的数,权值成2,对于拥有两个相同的质因子的数,权值除以2,对于拥有三个或者三个以上质因子的数,权值为零,最后求和。(卡常)
#include <bits/stdc++.h>
using namespace std; typedef long long ll;
const int maxn = 2e7 + ; int n;
int tot;
int isprime[maxn];
int prime[maxn];
int a[maxn];
int ans[maxn]; inline void Init_prime()
{
tot = ;
prime[] = ;
a[] = ;
ans[] = ;
for (register int i = ; i < maxn; ++i)
{
a[i] = ;
if (!isprime[i])
{
prime[tot++] = i; }
for (register int j = ; j < tot && i * prime[j] < maxn; ++j)
{
isprime[i * prime[j]] = ;
if (!(i % prime[j]))
{
break;
}
}
}
for (register int i = ; i < tot; ++i)
{
for (register int j = ; j * prime[i] < maxn; ++j)
{
a[j * prime[i]] <<= ;
}
if (prime[i] > maxn / prime[i]) continue;
for (register int j = ; j * prime[i] * prime[i] < maxn; ++j)
{
if (j % prime[i] == )
{
a[j * prime[i] * prime[i]] = ;
}
a[j * prime[i] * prime[i]] >>= ;
}
}
for (register int i = ; i < maxn; ++i)
{
ans[i] = ans[i - ] + a[i];
}
} int main()
{
Init_prime();
int t;
//cout << tot << endl;
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
printf("%d\n", ans[n]);
}
return ;
}
K. The Great Nim Game
留坑。
L. Magical Girl Haze
题意:有n个城市,m条边,可以令k条路权值为0,求1 - n 的最短路
思路:对于每个城市,枚举到这个城市,免费0-k次的权值,跑一个(立体的?)最短路
#include <bits/stdc++.h>
using namespace std; #define N 100010
#define ll long long
#define INFLL 0x3f3f3f3f3f3f3f3f struct Edge
{
int to, nx; ll w;
inline Edge() {}
inline Edge(int to, int nx, ll w) : to(to), nx(nx), w(w) {}
}edge[N << ]; int head[N], pos; inline void Init()
{
memset(head, -, sizeof head);
pos = ;
} inline void addedge(int u, int v, ll w)
{
edge[++pos] = Edge(v, head[u], w); head[u] = pos;
} struct node
{
int to, p; ll w;
inline node() {}
inline node(int to, int p, ll w) : to(to), p(p), w(w) {}
inline bool operator < (const node &r) const
{
return w > r.w;
}
}; ll dist[N][];
bool used[N][];
int t, n, m, k; inline void Dijkstra()
{
for (int i = ; i <= n; ++i) for (int j = ; j <= k; ++j) dist[i][j] = INFLL, used[i][j] = false;
priority_queue <node> q; q.emplace(, , ); dist[][] = ;
while (!q.empty())
{
int u = q.top().to;
int p = q.top().p;
ll w = q.top().w;
//cout << w << endl;
q.pop();
if (used[u][p]) continue;
used[u][p] = true;
dist[u][p] = w;
for (int i = head[u]; ~i; i = edge[i].nx)
{
int v = edge[i].to;
ll c = edge[i].w;
if (dist[u][p] + c < dist[v][p])
{
dist[v][p] = dist[u][p] + c;
q.emplace(v, p, dist[v][p]);
}
if (p + <= k && dist[u][p] < dist[v][p + ])
{
dist[v][p + ] = dist[u][p];
q.emplace(v, p + , dist[v][p + ]);
}
}
}
} inline void Run()
{
scanf("%d", &t);
while (t--)
{
Init();
scanf("%d%d%d", &n, &m, &k);
int u, v; ll w;
for (int i = ; i <= m; ++i)
{
scanf("%d%d%lld", &u, &v, &w);
addedge(u, v, w);
}
Dijkstra();
ll ans = dist[n][k];
printf("%lld\n", ans);
}
}
int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run(); return ;
}
ACM-ICPC 2018 南京赛区网络预赛 Solution的更多相关文章
- ACM-ICPC 2018 南京赛区网络预赛 E题
ACM-ICPC 2018 南京赛区网络预赛 E题 题目链接: https://nanti.jisuanke.com/t/30994 Dlsj is competing in a contest wi ...
- ACM-ICPC 2018 南京赛区网络预赛
轻轻松松也能拿到区域赛名额,CCPC真的好难 An Olympian Math Problem 问答 只看题面 54.76% 1000ms 65536K Alice, a student of g ...
- ACM-ICPC 2018 南京赛区网络预赛 J.sum
A square-free integer is an integer which is indivisible by any square number except 11. For example ...
- ACM-ICPC 2018 南京赛区网络预赛B
题目链接:https://nanti.jisuanke.com/t/30991 Feeling hungry, a cute hamster decides to order some take-aw ...
- 计蒜客 30999.Sum-筛无平方因数的数 (ACM-ICPC 2018 南京赛区网络预赛 J)
J. Sum 26.87% 1000ms 512000K A square-free integer is an integer which is indivisible by any squar ...
- 计蒜客 30996.Lpl and Energy-saving Lamps-线段树(区间满足条件最靠左的值) (ACM-ICPC 2018 南京赛区网络预赛 G)
G. Lpl and Energy-saving Lamps 42.07% 1000ms 65536K During tea-drinking, princess, amongst other t ...
- 计蒜客 30990.An Olympian Math Problem-数学公式题 (ACM-ICPC 2018 南京赛区网络预赛 A)
A. An Olympian Math Problem 54.28% 1000ms 65536K Alice, a student of grade 66, is thinking about a ...
- ACM-ICPC 2018 南京赛区网络预赛 B. The writing on the wall
题目链接:https://nanti.jisuanke.com/t/30991 2000ms 262144K Feeling hungry, a cute hamster decides to o ...
- ACM-ICPC 2018 南京赛区网络预赛 L. Magical Girl Haze
262144K There are NN cities in the country, and MM directional roads from uu to v(1\le u, v\le n)v ...
随机推荐
- js 正则表达式验证网站域名
正则表达式 ^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$
- DBA-mysql-授权
权限系统介绍 权限系统的作用是授予来自某个主机的某个用户可以查询.插入.修改.删除等数据库操作的权限. 不能明确的指定拒绝某个用户的连接. 权限控制(授权与回收)的执行语句包括create user, ...
- 【问题】Can't load AMD 64-bit .dll on a IA 32-bit platform
文件下载地址:http://archive.apache.org/dist/tomcat/tomcat-connectors/native/1.2.14/binaries/ 按自己的提示找到32位或者 ...
- Android学习:ActionBar活动条
菜单定义: <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android=" ...
- phpstorm webstorm 常用快捷键总结
1.全项目搜索 ctrl + shift + F 这个是window下的快捷键
- 动态性能视图v$mystat,v$sesstat,v$statname
视图说明: v$mystat-------> 当前会话统计 v$sesstat------> 按会话进行分组统计 v$sysstat-------> 当系统的整体统计 v$statn ...
- python基础类型—字符串
字符串str 用引号引起开的就是字符串(单引号,双引号,多引号) 1.字符串的索引与切片. 索引即下标,就是字符串组成的元素从第一个开始,初始索引为0以此类推. a = 'ABCDEFGHIJK' p ...
- Nestjs 链接mysql
文档 下插件 λ yarn add @nestjs/typeorm typeorm mysql 创建 cats模块, 控制器,service λ nest g mo cats λ nest g co ...
- Druid连接池(二)
DRUID是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0.DBCP.PROXOOL等DB池的优点,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况,可以说是针对监控而生的DB ...
- windows下怎样测试oracle安装是否成功以及在oracle中创建用户并赋予用户权限;和[Err] ORA-65096: 公用用户名或角色名无效的解决方案
测试oracle数据安装是否成功,可按顺序执行以下两个步骤: 测试步骤 1:请执行操作系统级的命令:tnsping orcl 上述命令假定全局数据库名是 orcl.以下是命令执行后的示例(请在cmd命 ...