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的更多相关文章

  1. 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 ...

  2. 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 ...

  3. 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 ...

  4. 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 ...

  5. 计蒜客 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  ...

  6. 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 ...

  7. 2019 The 19th Zhejiang University Programming Contest

    感想: 今天三个人的状态比昨天计院校赛的状态要好很多,然而三个人都慢热体质导致签到题wa了很多发.最后虽然跟大家题数一样(6题),然而输在罚时. 只能说,水题还是刷得少,看到签到都没灵感实在不应该. ...

  8. 2018-2019 Russia Open High School Programming Contest (Unrated, Online Mirror, ICPC Rules, Teams Preferred)

    前言 有一场下午的cf,很滋磁啊,然后又和dalao(见右面链接)组队打了,dalao直接带飞我啊. 这是一篇题解,也是一篇总结,当然,让我把所有的题目都写个题解是不可能的了. 按照开题顺序讲吧. 在 ...

  9. 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 ...

随机推荐

  1. 分享一句话的同时说说遍历map的常用方法

    最近在网上看到一句话,鄙人觉得这是比较经典的一句话,首先要给大家分享哈: 当一个人找不到出路的时候,最好的办法就是将当前能做好的事情做到极致,做到无人能及. Map<String, String ...

  2. IIC协议

    总线信号 :  SDA :串行数据线 SCL  :串行时钟 总线空闲状态 : SDA :高电平 SCL :高电平 起始位:SCL为高电平期间    SDA出现下降沿 终止位:SCL为高电平期间 SDA ...

  3. 关于js中定时器的返回值问题

    在js中,我们常常会用到定时器来处理各种各样的问题,当我们需要清除定时器的时候,我们常常会定义一个值来接受定时器的返回值,然后再把定义好的这个值写到清除定时器的括弧后面,如: var times = ...

  4. Spring学习笔记--初始化和销毁Bean

    可以使用bean的init-method和destroy-method属性来初始化和销毁bean.定义一个Hero类: package com.moonlit.myspring; public cla ...

  5. IIS禁止xml文件访问

    今天在出现数据库账号信息泄露的时候,突然想到xml文件里面放着很多信息,而且网页能够直接访问到,这就很有问题了 开始的时候,也在IIS网站那里看到请求筛选这个设置,开始还以为不能加呢,还是同事说的.

  6. sencha touch 入门系列 (六)sencha touch运行及代码解析(下)

    接着上一讲,通过index.html里development.js对app.json里js资源文件的解析,app.js便被index.html引入了, app.js是整个项目的程序入口,在项目完成时使 ...

  7. 【黑金原创教程】【Modelsim】Modelsim原创教程连载导读【连载完成,共六章】

    [第一章]Modelsim仿真的扫盲文 [第二章]Modelsim就是电视机 [第三章]理想就是美丽 [第四章]激励文本就是仿真环境 [第五章]仿真就是人生 [第六章]结束就是开始

  8. xcode官网下载地址

    https://developer.apple.com/downloads/

  9. numeric_limits 模板的相关知识点

    说白了,它是一个模板类,它主要是把C++当中的一些内建型别进行了封装,比如说numeric_limits<int>是一个特化后的类,从这个类的成员变量与成员函数中,我们可以了解到int的很 ...

  10. Nginx配置ssl安全证书

    server { listen 443; server_name www.loaclhost.com; ssl on; root /web; ssl_certificate /data/ssl/xxx ...