2018-2019 Russia Open High School Programming Contest
A. Company Merging
Solved.
温暖的签到。
#include<bits/stdc++.h> using namespace std; const int maxn = 2e5 + ; typedef long long ll; struct node{
int val, num;
node(){}
node(int val, int num):val(val), num(num){}
}arr[maxn]; int n, m; int main()
{
while(~scanf("%d", &n))
{
int Max = ;
for(int i = ; i <= n; ++i)
{
scanf("%d", &arr[i].num);
arr[i].val = ;
for(int j = , x; j <= arr[i].num; ++j)
{
scanf("%d", &x);
arr[i].val = max(arr[i].val, x);
}
Max = max(arr[i].val, Max);
}
ll ans = ;
for(int i = ; i <= n; ++i)
{
// cout << arr[i].val << " " << endl;
ans += 1ll * arr[i].num * (Max - arr[i].val);
}
printf("%lld\n", ans);
}
return ;
}
B. LaTeX Expert
Solved.
按题意模拟即可。
#include <bits/stdc++.h>
using namespace std; #define N 100010
string str, s;
string st = "\\begin{thebibliography}{99}";
string ed = "\\end{thebibliography}";
map <string, int> mp;
int cnt, now; bool same;
string res[N]; int getid(string s)
{
if (mp.find(s) == mp.end()) mp[s] = ++cnt;
return mp[s];
} void work()
{
int len = str.size();
string tmp = ""; bool add = ;
for (int i = ; i < len; ++i)
{
if (str[i] == '{') add = ;
else if (str[i] == '}')
{
getid(tmp);
tmp = "";
add = ;
}
else if (add) tmp += str[i];
}
} void add()
{
int len = s.size();
string tmp = ""; bool add = ;
for (int i = ; i < len; ++i)
{
if (s[i] == '{') add = ;
else if (s[i] == '}')
{
++now;
int id = getid(tmp);
if (id != now) same = false;
res[id] = s;
return;
}
else if (add)
tmp += s[i];
}
} int main()
{
ios::sync_with_stdio(false);
cin.tie(); cout.tie();
cnt = ; now = ;
bool start = ;
same = true;
str = "";
while (getline(cin, s))
{
if (s == "") continue;
if (s == st)
{
start = ;
work();
continue;
}
if (s == ed)
{
if (same)
{
cout << "Correct\n";
return ;
}
cout << "Incorrect\n";
cout << st << "\n";
for (int i = ; i <= cnt; ++i)
cout << res[i] << "\n";
cout << ed << "\n";
}
if (start)
add();
else
str += s;
}
return ;
}
C. New Year Presents
Upsolved.
题意:
有$n$个小朋友,每个小朋友有$s_i$件不同的物品,一个小朋友可以将自己的一件物品给另一个小朋友,前提是另一个小朋友没有这件物品,这样记为一次转移
求最少的转移次数使得拥有最多数量物品的小朋友和拥有最少数量物品的小朋友他们拥有的物品数量差值不超过1.
思路:
首先拥有东西多的小朋友肯定能往拥有东西少的小朋友转移(根据鸽笼原理),那只要把物品多的小朋友放在一起,然后去转移给物品少的小朋友就好了
注意枚举的技巧,复杂度应该跟$O(n)有关?$
#include <bits/stdc++.h>
using namespace std; #define N 100010
struct node
{
int l, r, x;
node () {}
node (int l, int r, int x) : l(l), r(r), x(x) {}
};
vector <int> vec[N];
int n, m;
int vis[N];
vector <node> res;
int a[N * ], now[N], nx[N * ], last;
int sze[N];
queue <int> q; void add(int x, int id)
{
a[++last] = x;
nx[last] = now[id];
now[id] = last;
} int main()
{
while (scanf("%d%d", &n, &m) != EOF)
{
int tot = ;
res.clear();
memset(now, , sizeof now);
for (int i = , x, y; i <= n; ++i)
{
scanf("%d", &x);
tot += x;
vec[i].clear();
for (int j = ; j <= x; ++j)
{
scanf("%d", &y);
vec[i].push_back(y);
}
sze[i] = vec[i].size();
}
if (tot % n == )
{
int x = tot / n;
for (int i = ; i <= n; ++i)
if (sze[i] > x)
for (auto it : vec[i])
add(i, it);
for (int i = ; i <= m; ++i)
if (now[i]) q.push(i);
for (int i = , front; i <= n; ++i)
if (sze[i] < x)
{
for (auto it : vec[i])
vis[it] = ;
while (sze[i] < x)
{
front = q.front(); q.pop();
//printf("%d %d %d\n", i, sze[i], front);
if (vis[front])
{
q.push(front);
continue;
}
int id = now[front];
for (; id ; id = nx[id])
{
if (sze[a[id]] <= x) continue;
res.push_back(node(a[id], i, front));
vec[i].push_back(front);
vis[front] = ;
--sze[a[id]];
++sze[i];
id = nx[id];
break;
}
if (id) q.push(front);
now[front] = id;
}
for (auto it : vec[i])
vis[it] = ;
}
}
else
{
int x = tot / n + ;
int need = n - tot % n;
for (int i = ; i <= n; ++i)
if (sze[i] > x)
for (auto it : vec[i])
add(i, it);
for (int i = ; i <= m; ++i)
if (now[i]) q.push(i);
for (int i = , front; i <= n; ++i)
if (sze[i] < x)
{
if (sze[i] == x - && need)
{
--need;
continue;
}
for (auto it : vec[i])
vis[it] = ;
while (sze[i] < x)
{
if (sze[i] == x - && need)
{
--need;
break;
}
front = q.front(); q.pop();
if (vis[front])
{
q.push(front);
continue;
}
int id = now[front];
for (; id; id = nx[id])
{
if (sze[a[id]] <= x) continue;
res.push_back(node(a[id], i, front));
vec[i].push_back(front);
vis[front] = ;
--sze[a[id]];
++sze[i];
id = nx[id];
break;
}
if (id) q.push(front);
now[front] = id;
}
for (auto it : vec[i])
vis[it] = ;
}
}
int len = res.size();
printf("%d\n", len);
for (int i = ; i < len; ++i)
printf("%d %d %d\n", res[i].l, res[i].r, res[i].x);
}
return ;
}
D. Similar Arrays
Solved.
找到一组没有任何关系的$i, j$填上1/1, 1/2, 其他的分别填入3-n。
#include<bits/stdc++.h> using namespace std; const int maxn = 1e5 + ; int n, m;
set<int>s[maxn];
int arr[maxn], brr[maxn]; void solve()
{
for(int i = ; i <= n; ++i)
{
for(int j = i + ; j <= n; ++j) if(s[i].count(j) == )
{
arr[i] = , arr[j] = ;
brr[i] = , brr[j] = ;
int pos = ;
for(int k = ; k <= n; ++k)if(!arr[k])
{
arr[k] = brr[k] = pos++;
}
puts("YES");
for(int k = ; k <= n; ++k) printf("%d%c", arr[k], " \n"[k == n]);
for(int k = ; k <= n; ++k) printf("%d%c", brr[k], " \n"[k == n]);
return ;
}
}
puts("NO");
} int main()
{
while(~scanf("%d %d", &n, &m))
{
for(int i = ; i <= n; ++i) s[i].clear(), arr[i] = brr[i] = ;
for(int i = , l, r; i <= m; ++i)
{
scanf("%d %d", &l, &r);
s[min(l, r)].insert(max(l, r));
}
solve();
}
return ;
}
E. Horseback Riding
Solved.
枚举每个终点, 跑一边$BFS$, 暴力搜索, 记录状态。
#include<bits/stdc++.h> using namespace std; const int maxn = 1e2 + ; int n;
vector<pair<int, int> >ans;
char str[maxn];
int vis[maxn];
int dis[maxn];
int pre[maxn];
int dir[][] = {, , , -, -, , -, -, , , , -, -, , -, -}; bool judge(int x, int y)
{
if(x < || x >= || y < || y >= || dis[x * + y]) return false;
else return true;
} void BFS(int st)
{
memset(dis, , sizeof dis);
memset(pre, -, sizeof pre);
queue<int>q;
q.push(st);
dis[st] = ;
while(!q.empty())
{
int x = q.front() / ;
int y = q.front() % ;
q.pop();
for(int j = ; j < ; ++j)
{
int dx = x + dir[j][];
int dy = y + dir[j][];
if(judge(dx, dy))
{
dis[dx * + dy] = dis[x * + y] + ;
pre[dx * + dy] = x * + y;
q.push(dx * + dy);
}
}
}
} int main()
{
while(~scanf("%d", &n))
{
memset(vis, , sizeof vis);
ans.clear();
for(int i = ; i <= n; ++i)
{
scanf("%s", str);
vis[(str[] - '') * + str[] - 'a'] = ;
}
ans.clear();
for(int i = ; i < n; ++i)
{
BFS(i);
int ed = i;
while(!vis[ed]) ++ed;
vis[ed] = ;
while(ed != i)
{
vector<int>path;
do{
path.push_back(ed);
ed = pre[ed];
}while(vis[ed]);
path.push_back(ed);
for(int j = path.size() - ; j >= ; --j) ans.push_back(make_pair(path[j - ], path[j]));
}
vis[ed] = ;
}
int len = ans.size();
printf("%d\n", len);
for(auto it : ans)
{
printf("%c%d-%c%d\n", it.first % + 'a', it.first / + , it.second % + 'a', it.second / + );
}
}
return ;
}
F. How to Learn You Score
Upsolved.
题意:
有$n$个数,每次可以询问三个数,返回这三个数的最大值+最小值的和,用不超过$4 \cdot n$次的询问求出这$n$个数是什么
思路:
考虑$4$个数的时候,一共有$4$种询问方式,将这四种询问方式得到的四个值取最大最小值加起来就是这四个值的和
那么五个数我们就得到任意四个数的和,我们令$sum_i$表示不包含第$i$个数的和
那么有
$a_i + sum_i = a_j + sum_j$
有
$a_1 + sum_1 = a_2 + sum_2 = a_3 + sum_3 = a_4 + sum_4 = a_5 + sum_5$
联立后有
$4 \cdot a_1 = \sum\nolimits_{i = 1}^{5} sum_i - 4 \cdot sum_1$
依次求出这五个数
然后考虑后面的数可以用前面已知的数通过四次询问推出
总的询问次数$4 \cdot n$
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 1010
int n;
ll a[N]; void work(int l, int r)
{
int ord[]; ll sum[];
for (int i = , j = l; i <= ; ++i, ++j)
ord[i] = j;
//for (int i = 1; i <= 5; ++i) printf("%d%c", ord[i], " \n"[i == 5]);
for (int i = ; i <= ; ++i)
{
vector <ll> vec;
int id[], id2[];
ll x;
for (int j = , k = ; j <= ; ++j)
if (i != j)
id[++k] = ord[j];
//for (int j = 1; j <= 4; ++j)
// printf("%d%c", id[j], " \n"[j == 4]);
for (int j = ; j <= ; ++j)
{
for (int k = , o = ; k <= ; ++k)
if (j != k)
id2[++o] = id[k];
printf("? ");
for (int k = ; k <= ; ++k)
printf("%d%c", id2[k], " \n"[k == ]);
fflush(stdout);
scanf("%lld", &x);
vec.push_back(x);
}
sort(vec.begin(), vec.end());
sum[i] = vec.end()[-] + *vec.begin();
}
//for (int i = 1; i <= 5; ++i)
// printf("%lld%c", sum[i], " \n"[i == 5]);
ll tot = ;
for (int i = ; i <= ; ++i)
tot += sum[i];
for (int i = ; i <= ; ++i)
{
//assert((4ll * sum[i] - tot) % 4 == 0);
a[l + i - ] = -(4ll * sum[i] - tot) / ;
}
} ll get(int l, int r)
{
int id[], id2[];
vector <ll> vec;
ll x;
for (int i = ; i <= ; ++i)
id[i] = i + l - ;
for (int j = ; j <= ; ++j)
{
for (int k = , o = ; k <= ; ++k)
if (j != k)
id2[++o] = id[k];
printf("? ");
for (int k = ; k <= ; ++k)
printf("%d%c", id2[k], " \n"[k == ]);
fflush(stdout);
scanf("%lld", &x);
vec.push_back(x);
}
sort(vec.begin(), vec.end());
return vec.end()[-] + *vec.begin();
} int main()
{
while (scanf("%d", &n) != EOF)
{
work(, );
for (int i = ; i <= n; ++i)
{
ll tot = get(i - , i);
for (int j = i - ; j < i; ++j)
tot -= a[j];
a[i] = tot;
}
printf("! ");
for (int i = ; i <= n; ++i)
printf("%lld%c", a[i], " \n"[i == n]);
fflush(stdout);
}
return ;
}
I. Minimal Product
Solved.
题意:求一个序列$找一个最小的a_i \cdot a_j 并且满足i < j, a_i < a_j$
思路:
正着扫一遍维护最小值,倒着扫一遍维护最大值。
注意生成序列的时候的取模,要自然溢出,否则会爆ll
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll MOD = 1ll << ;
const ll INFLL = 5e18;
const int maxn = 1e7 + ; ll n, l, r;
ll arr[maxn];
unsigned int x, y,z, b1, b2;
unsigned int brr[maxn]; int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%lld %lld %lld %u %u %u %u %u", &n, &l, &r, &x, &y, &z, &b1, &b2);
brr[] = b1;
brr[] = b2;
for(int i = ; i <= n; ++i) brr[i] = (brr[i - ] * x + brr[i - ] * y + z);
for(int i = ; i <= n; ++i) arr[i] = (brr[i] % (r - l + ) + l);
int flag = ;
ll ans = INFLL;
ll Max = -INFLL;
for(int i = n; i >= ; --i)
{
if(arr[i] < Max)
{
flag = ;
ans = min(ans, arr[i] * Max);
}
Max = max(Max, arr[i]);
}
ll Min = INFLL;
for(int i = ; i <= n; ++i)
{
if(arr[i] > Min)
{
flag = ;
ans = min(ans, arr[i] * Min);
}
Min = min(Min, arr[i]);
}
if(!flag) puts("IMPOSSIBLE");
else printf("%lld\n", ans);
}
return ;
}
K. Right Expansion Of The Mind
Solved.
分为s, t两个字符串讨论。
对于t字符串, 只要两个t字符串含有相同字母即可。
对于s字符串, 从后往前删除在t字符串中的字符, 知道找到一个不在t字符串中的字符, 那么另一个可以匹配的字符串, 前缀相同。
#include<bits/stdc++.h> using namespace std; int n;
string s, t;
map<pair<string, int>, vector<int> >mp; int main()
{
ios::sync_with_stdio(false);
cin.tie(); cout.tie();
while(cin >> n)
{
mp.clear();
for(int i = ; i <= n; ++i)
{
cin >> s >> t;
int tmp = ;
for(int j = , len = t.length(); j < len; ++j) tmp |= ( << (t[j] - 'a'));
int len = s.length();
for(int j = len - ; j >= ; --j)
{
if(tmp & ( << (s[j] - 'a'))) s.erase(s.begin() + j);
else break;
}
mp[make_pair(s, tmp)].push_back(i);
}
int res = mp.size();
cout << res << "\n";
for(auto vec : mp)
{
int len = vec.second.size();
cout << len;
for(auto it : vec.second)
{
cout << " " << it;
}
cout << "\n";
}
}
return ;
}
L. erland University
Solved.
二分答案。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int INF = 0x3f3f3f3f; ll t, n, a, b, k; bool check(ll mid)
{
ll res = mid * k;
ll tmp = min(a, mid) * (n / + n % ) + min(b, mid) * (n / );
return res <= tmp;
} int main()
{
while(~scanf("%lld %lld %lld %lld %lld", &t ,&n, &a, &b, &k))
{
ll l = , r = t, res = ;
while(r - l >= )
{
ll mid = (l + r) >> ;
if(check(mid))
{
l = mid + ;
res = mid;
}
else
{
r = mid - ;
}
}
printf("%lld\n", res);
}
return ;
}
M. The Pleasant Walk
Solved.
温暖的签到。
#include<bits/stdc++.h> using namespace std; const int maxn = 1e5 + ; int n, k;
int dp[maxn];
int arr[maxn]; int main()
{
while(~scanf("%d %d", &n, &k))
{
int ans = ;
memset(dp, , sizeof dp);
for(int i = ; i <= n; ++i) scanf("%d", arr + i);
for(int i = ; i <= n; ++i)
{
dp[i] = ;
if(arr[i] != arr[i - ]) dp[i] = max(dp[i - ] + , dp[i]);
ans = max(ans, dp[i]);
}
printf("%d\n", ans);
}
return ;
}
2018-2019 Russia Open High School Programming Contest的更多相关文章
- Codeforces 1090A - Company Merging - [签到水题][2018-2019 Russia Open High School Programming Contest Problem A]
题目链接:https://codeforces.com/contest/1090/problem/A A conglomerate consists of n companies. To make m ...
- Codeforces 1090B - LaTeX Expert - [字符串模拟][2018-2019 Russia Open High School Programming Contest Problem B]
题目链接:https://codeforces.com/contest/1090/problem/B Examplesstandard input The most famous characters ...
- Codeforces 1090D - Similar Arrays - [思维题][构造题][2018-2019 Russia Open High School Programming Contest Problem D]
题目链接:https://codeforces.com/contest/1090/problem/D Vasya had an array of n integers, each element of ...
- Codeforces 1090M - The Pleasant Walk - [签到水题][2018-2019 Russia Open High School Programming Contest Problem M]
题目链接:https://codeforces.com/contest/1090/problem/M There are n houses along the road where Anya live ...
- 计蒜客 39272.Tree-树链剖分(点权)+带修改区间异或和 (The 2019 ACM-ICPC China Shannxi Provincial Programming Contest E.) 2019ICPC西安邀请赛现场赛重现赛
Tree Ming and Hong are playing a simple game called nim game. They have nn piles of stones numbered ...
- CF_2018-2019 Russia Open High School Programming Contest (Unrated, Online Mirror, ICPC Rules, Teams Preferred)
只做了两个就去上课去啦... A. Company Merging time limit per test 1 second memory limit per test 512 megabytes i ...
- 2019 The 19th Zhejiang University Programming Contest
感想: 今天三个人的状态比昨天计院校赛的状态要好很多,然而三个人都慢热体质导致签到题wa了很多发.最后虽然跟大家题数一样(6题),然而输在罚时. 只能说,水题还是刷得少,看到签到都没灵感实在不应该. ...
- 2018-2019 Russia Open High School Programming Contest (Unrated, Online Mirror, ICPC Rules, Teams Preferred)
前言 有一场下午的cf,很滋磁啊,然后又和dalao(见右面链接)组队打了,dalao直接带飞我啊. 这是一篇题解,也是一篇总结,当然,让我把所有的题目都写个题解是不可能的了. 按照开题顺序讲吧. 在 ...
- C.0689-The 2019 ICPC China Shaanxi Provincial Programming Contest
We call a string as a 0689-string if this string only consists of digits '0', '6', '8' and '9'. Give ...
随机推荐
- python2.0 s12 day8 _ python线程&python进程
1.进程.与线程区别2.cpu运行原理3.python GIL全局解释器锁4.线程 1.语法 2.join 3.线程锁之Lock\Rlock\信号量 4.将线程变为守护进程 5.Event事件 6.q ...
- List自定义排序
List自定义排序我习惯根据Collections.sort重载方法来实现,下面我只实现自己习惯方式.还有一种就是实现Comparable接口. 挺简单的,直接上代码吧. package com.so ...
- osgEarth使用没有DX的Triton库Triton-MT-DLL-NODX.lib
将Triton-MT-DLL修改为Triton-MT-DLL-NODX
- nutch 存储到数据库
就像我们知道的一样,nutch是一个架构在lucene之上的网络爬虫+搜索引擎. 是由lucene的作者在lucene基础之上开发,并整合了hadoop,实现在分布式云计算,使用google标准的HF ...
- 初学hadoop,windows下安装
先bb一下,woc开始使用Cygwin来模拟linux配置hadoop,然后各种错误,找着找着发现原来2.0+的hadoop可以直接在windows下配置.当时真是1w头神兽飞过. 下载hadoop ...
- Java的String详解
Java的String详解 博客分类: Java javaStringString详解常用方法 Java的String类在开发时经常都会被使用到,由此可见String的重要性.经过这次认真仔细的学习 ...
- Elasticsearch配置参数介绍
Elasticsearch的config文件夹里面有两个配置文件:elasticsearch.yml和logging.yml.第一个是es的基本配置文件,第二个是日志配置文件,es也是使用log4j来 ...
- js嵌套轮播图
$(function(){ var navLi = $(".top_nav").find("li"), conDiv = $(".top_con&qu ...
- Python 中的线程-进程2
原文:https://www.cnblogs.com/i-honey/p/7823587.html Python中实现多线程需要使用到 threading 库,其中每一个 Thread类 的实例控制一 ...
- sublime3095-注册码下载安装
链接:http://pan.baidu.com/s/1hqejFKS 下载地址:下载 提取密码:egh5 ----- BEGIN LICENSE ----- Andrew Weber Single U ...