SnackDown Online Pre-elimination round A
1. 应该n是偶数,就行吧。应该判断1个人,只能出现一次吧。
#include<bits/stdc++.h>
#define pb push_back
typedef long long ll;
using namespace std;
typedef pair<int, int> pii;
const int maxn = 1e3 + ; void yes() {cout << "yes" << endl;}
void no() {cout << "no" << endl; }
int n, c;
int a[];
void solve() {
memset(a, , sizeof a);
cin >> n >> c;
int x, y;
bool tag = ;
for (int i = ; i < c; i++) {
cin >> x >> y;
if(a[x] || a[y]) tag = ;
a[x] = a[y] = ;
}
if(n % == || tag) no();
else yes();
} int main() {
// freopen("test.in", "r", stdin);
//freopen("test.out", "w", stdout);
ios::sync_with_stdio();
cin.tie(); cout.tie();
int _;
cin >> _;
while(_--)
solve();
return ;
}
2. 是否是一条蛇,这个浪费了一些时间。
首先#必须组成1个连通分量,多于1个的,肯定是不行的。然后还有其他情况。判断连通分量, dfs或者bfs扫就行。
1个连通分量怎么是一条蛇,我刚开始以为是dfs扫一遍,每一个点的只能有一个前驱和后继,但是这样枚举的复杂度很高,应该会tle。
考虑到只有2行,然后总左到右进行考虑, 每次先考虑上下, 再考虑向右走,然后check,长度是否是#的个数。注意,最左边的点,可能第一个是第一行往下走,或者是第二行往上走,都是可以的。
写的有点丑。
#include<bits/stdc++.h>
#define pb push_back
typedef long long ll;
using namespace std;
typedef pair<int, int> pii;
const int maxn = 1e3 + ;
int n;
string s[];
int c;
int cnt;
bool vis[][];
int dx[] = {, , , -};
int dy[] = {, -, , };
bool check(int x, int y) {
if(x >= && x < && y >= && y < n) return ;
return ;
}
void dfs(int x, int y) {
if(vis[x][y] || s[x][y] == '.') return;
vis[x][y] = ;
cnt++;
for (int i = ; i < ; i++) {
int cx = x + dx[i], cy = y + dy[i];
if(check(cx, cy)) {
dfs(cx, cy);
}
}
}
void yes() {cout << "yes" << endl; }
void no() {cout << "no" << endl; }
void solve() {
cin >> n;
cin >> s[] >> s[];
//cout << s[0] << " " << s[1] << endl;
c = ;
for (int i = ; i < n; i++) {
if(s[][i] == '#') c++;
if(s[][i] == '#') c++;
}
int x, y;
x = y = -;
for (int j = ; j < n; j++) {
for (int i = ; i < ; i++) {
if(s[i][j] == '#') {
x = i; y = j;
break;
}
}
if(x != -) break;
}
cnt = ;
memset(vis, , sizeof vis);
dfs(x, y);
//cout << x << " " << y << endl;
//cout << c << " " << cnt << endl;
if(cnt != c) {
no(); return;
}
memset(vis, , sizeof vis);
int dx = x, dy = y;
//cout << x << " " << y << endl;
while(cnt > ) {
vis[x][y] = ;
cnt--;
if(cnt == ) break;
if(s[ - x][y] == '#' && !vis[ - x][y]) {
x = - x;
} else if(y + < n && s[x][y + ] == '#') {
y = y + ;
} else {
break; }
}
if(cnt == ) {
yes(); return;
}
cnt = c;
//cout << x << " d " << y << endl;
x = - dx, y = dy; if(s[x][y] != '#') {
no(); return;
}
memset(vis, , sizeof vis);
while(cnt > ) {
vis[x][y] = ;
cnt--;
if(cnt == ) break;
if(s[ - x][y] == '#' && !vis[ - x][y]) {
x = - x;
} else if(y + < n && s[x][y + ] == '#') {
y = y + ;
} else {
no();
return; }
}
yes();
} int main() {
// freopen("test.in", "r", stdin);
//freopen("test.out", "w", stdout);
//ios::sync_with_stdio(0);
//cin.tie(0); cout.tie(0);
int _; cin >> _;
while(_--)
solve();
return ;
}
3. 这个题目跟资格赛的题目有点像,但是比较难。考虑每个位置的上限是多少,多于这个数,肯定是要必须操作的。
是这样的形式, 1, 2,3 。。。3,2,1, 首先经过这样的缩减。找到必须的操作。 同时又可以观察到,如果第二个数为1, 然后第三个位置的上限就变为2了,而不是3. 这点也很容易想到。每个点只影响左右的点,然后左右的
点,再把这个值传递出去。最后的结果肯定是,没相邻的2个点,最多相差1,而且每个位置的值,都是这个位置可以到达的上限。然后操作,就很简单了,枚举每一个点作为中心, 用所有和减去这个数, 求的最小的需要操作次数,
最后,别忘了加上必须的操作次数。
#include<bits/stdc++.h>
#define pb push_back
typedef long long ll;
using namespace std;
typedef pair<int, int> pii;
const int maxn = 1e5 + ; int n;
int a[maxn];
void solve() {
scanf("%d", &n);
ll s = ;
for (int i = ; i <= n; i++) {
scanf("%d", &a[i]);
}
for (int i = ; i <= n / ; i++) {
//cout << i << " " << a[i] << endl;
//cout << n + 1 - i << " " << a[n + 1 - i] << endl;
if(a[i] > i) {
s += a[i] - i;
a[i] = i;
}
if(a[n + - i] > i) {
s += a[n + - i] - i;
a[n + - i] = i;
}
}
n++;
if(n % == ) {
if(a[n / ] > n / ) {
s += a[n / ] - n / ;
a[n / ] = n / ;
}
}
n--;
//for (int i = 1; i <= n; i++)
//cout << i << " ad " << a[i] << endl;
set<pii> se;
for (int i = ; i <= n; i++) {
se.insert({a[i], i });
}
int x, y;
while(!se.empty()) {
pii t = *se.begin();
se.erase(se.begin());
y = t.first; x = t.second;
if(x - > ) {
if(a[x - ] > y + ) {
se.erase({a[x - ], x - });
s += a[x - ] - y - ;
a[x - ] = y + ;
se.insert({a[x - ], x - });
}
}
if(x + <= n) {
if(a[x + ] > y + ) {
se.erase({a[x + ], x + });
s += a[x + ] - y - ;
a[x + ] = y + ;
se.insert({a[x + ], x + } );
}
}
}
//for (int i = 1; i <= n; i++)
// cout << i << " " << a[i] << endl;
ll ts = ;
for (int i = ; i <= n; i++)
ts += a[i];
ll res = INT_MAX;
for (int i = ; i <= n; i++) {
res = min(res, ts - a[i] * a[i]);
}
printf("%lld\n", s + res); } int main() {
//freopen("test.in", "r", stdin);
//freopen("test.out", "w", stdout);
int _;
scanf("%d", &_);
while(_--)
solve();
return ;
}
4. 连续的蛇,这个题写出目标方程,很容易简化为就是一个区间求一个点, 使得这些点到目标n个点的差的绝对值和最小。显然是一个二分问题,应该是凹的,但是,是整数上的,所以,用二分很容易做。
#include<bits/stdc++.h>
#define pb push_back
typedef long long ll;
using namespace std;
typedef pair<int, int> pii;
const int maxn = 1e5 + ; int n;
ll l, a, b;
ll s[maxn]; ll work(ll x) {
ll r = ;
for (int i = ; i < n; i++)
r += abs(s[i] - x);
return r;
}
void solve() {
scanf("%d%lld%lld%lld", &n, &l, &a, &b);
for (int i = ; i < n; i++) {
scanf("%lld", &s[i]);
}
sort(s, s + n);
for (int i = ; i < n; i++)
s[i] -= i * l;
//sort(s, s + n);
ll left = a, right = b - n * l;
ll ta = left, tb = right;
while(left < right) {
ll mid = (left + right) / ;
ll x1 = work(mid - ), x2 = work(mid), x3 = work(mid + );
if(x2 <= x1 && x2 <= x3) {
left = right = mid;
} else if(x1 <= x2 && x2 <= x3) {
right = mid - ;
} else {
left = mid + ;
}
//cout << left << " " << right << endl;;
}
if(left < ta) left = ta;
if(left > tb) left = tb;
printf("%lld\n", work(left)); } int main() {
//freopen("test.in", "r", stdin);
//freopen("test.out", "w", stdout);
int t;
scanf("%d", &t);
while(t--)
solve();
return ;
}
5. 保卫毒药,就是一个区间问题,注意到一条蛇,只会贡献水平或者垂直二选一,不能同时贡献。 然后先区分水平和垂直的线段, 然后转化为一维问题, 有一些线段, 求使得覆盖目标区间,最少需要多少线段。这个题目应该是比较
简单的吧,排序,然后遍历一般就可以了。 我手残,居然错了好几次。果然以前想的不明白,写的不熟练。
代码写的很丑的。
#include<bits/stdc++.h>
#define pb push_back
typedef long long ll;
using namespace std;
typedef pair<int, int> pii;
const int maxn = 1e5 + ; int n, k, m;
int a[maxn][];
int tleft, tright;
bool check(int x, int y, int x1, int y1) {
//cout << x << " " << y << " " << x1 << " " << y1 << endl;
if(y < x1 || x > y1) return ;
return ;
}
int res;
bool f1, f2;
void work(vector<pii> & v, bool &f) {
f = ;
if(v.size() == || v[].first > tleft) {
f = ;
return;
}
int cur = tleft, r = tleft;
int cnt = ;
int x, y;
bool in = ;
for (int i = ; i < v.size(); i++) {
x = v[i].first, y = v[i].second;
//cout << x << " " << y << " " << cur << " " << r << endl;
if(x > r + ) {
f = ; return;
}
if(x <= cur) {
if(y >= r) {
in = ;
r = y;
}
if(i == v.size() - && in) {
cnt++;
r++;
}
} else {
cnt++;
r++;
if(r > tright) break;
cur = r; in = ;
i--;
} }
//cnt++;
if(r <= tright) f = ;
//cout << "r " << r << endl;
//cout << "cnt " << cnt << endl;
res += cnt;
}
void solve() {
scanf("%d%d%d", &n, &k, &m);
f1 = f2 = ;
for (int i = ; i < m; i++) {
for (int j = ; j < ; j++)
scanf("%d", &a[i][j]);
}
res = ;
tleft = (n - k) / + ;
tright = tleft + k - ;
//cout << tleft << " ads " << tright << endl;
vector<pii> v1, v2;
for (int i = ; i < m; i++) {
int x, y;
x = min(a[i][], a[i][]);
y = max(a[i][], a[i][]);
if(check(x, y, tleft, tright)) {
//cout << x << " c1 " << y << endl;
v1.pb({x, y});
}
x = min(a[i][], a[i][]);
y = max(a[i][], a[i][]);
if(check(x, y, tleft, tright)) { v2.pb({x,y});
}
}
sort(v1.begin(), v1.end());
v1.erase(unique(v1.begin(), v1.end()), v1.end());
sort(v2.begin(), v2.end());
v2.erase(unique(v2.begin(), v2.end()), v2.end());
work(v1, f1);
//cout << "asd" <<endl;
work(v2, f2);
if(f1 || f2) {
puts("-1");
} else {
printf("%d\n", res);
}
} int main() {
//freopen("test.in", "r", stdin);
//freopen("test.out", "w", stdout);
int _;
scanf("%d", &_);
while(_--)
solve();
return ;
}
6. 不会做。 后来发现,题目都没有仔细阅读,条件都没想清楚。 有时间看一下别人的题解吧。
Pre-elimination round B。 也开始了,但是round a过了,就不让做b了,我也没有看。就这样吧。
看的别人的代码,就是先把点移动到左上角,然后一次做删除, 删除每一行。注意边界条件。
#include<bits/stdc++.h>
#define pb push_back
typedef long long ll;
using namespace std;
typedef pair<int, int> pii;
const int maxn = 1e3 + ;
int n, m;
string s;
vector<pair<pii, pii>> ans;
void print(pair<pii, pii> t) {
cout << t.first.first << " " << t.first.second << " " << t.second.first << " " << t.second.second << endl;
}
void moveToTopLeft(int x, int y) {
for (int i = y - ; i > ; i--) {
ans.pb({{x, i}, {x, i + }});
}
for (int i = x - ; i > ; i--) {
ans.pb({{i, }, {i + , } });
}
}
void playrow(int x) {
for (int i = ; i <= m; i++) {
ans.pb({{x, i}, {x, i - } });
ans.pb({{x, i - }, {x, i - }});
ans.pb({{x, i - }, {x, i} } );
}
} void playcol(int x) {
for (int i = ; i <= n; i++) {
ans.pb({{i, x}, {i - , x} });
ans.pb({{i - , x}, {i - , x} });
ans.pb({{i - , x}, {i, x} });
}
}
void solve() {
cin >> n >> m;
int x, y;
x = y = ;
ans.clear();
for (int i = ; i <= n; i++) {
cin >> s;
for (int j = ; j <= m; j++) {
if(s[j - ] == '.') {
x = i; y = j;
}
}
}
if(n * m == ) {
puts("");
return;
}
if(n < && m < ) {
puts("-1");
return;
}
moveToTopLeft(x, y);
if(m == ) {
playcol();
} else if(m == ) {
playcol();
ans.pb({{, }, {, } });
ans.pb({{, }, {, } });
ans.pb({{, }, {, } });
ans.pb({{, }, {, } });
ans.pb({{, }, {, } });
ans.pb({{, }, {, } });
playcol();
ans.pb({{n, }, {n - , } });
ans.pb({{n - , }, {n - , } });
ans.pb({{n, }, {n - , } });
} else {
playrow();
for (int i = ; i <= n; i++) {
ans.pb({{i, }, {i - , } });
ans.pb({{i, }, {i, } });
ans.pb({{i, }, {i, } });
ans.pb({{i, }, {i, } });
ans.pb({{i - , }, {i, } } );
ans.pb({{i, }, {i, } } );
playrow(i);
}
if(n == ) { } else if(n == ) {
ans.pb({{, m}, {, m - } });
ans.pb({{, m - }, {, m - } });
ans.pb({{, m}, {, m - } });
} else {
ans.pb({{, m}, {, m - } });
ans.pb({{, m - }, {, m - } });
ans.pb({{, m}, {, m - } });
ans.pb({{, m - }, {, m - } });
ans.pb({{, m - }, {, m} });
playcol(m);
}
}
cout << ans.size() << endl;
for (auto t : ans)
print(t);
} int main() {
freopen("test.in", "r", stdin);
//freopen("test.out", "w", stdout);
int _;
cin >> _;
while(_--)
solve();
return ;
}
SnackDown Online Pre-elimination round A的更多相关文章
- [codechef]SnackDown 2017 Online Elimination Round Prefix XOR
预处理后主席树维护 首先得出最后的答案为 \(\sum_{i=l}^{r}{min(right[i],r)-i+1}\) \(ri[i]\)表示i最远的上升序列(即代码中的f[i]) step1 那么 ...
- 【CF1146】Forethought Future Cup - Elimination Round
Forethought Future Cup - Elimination Round 窝也不知道这是个啥比赛QwQ A. Love "A" 给你一个串,你可以删去若干个元素,使得最 ...
- CF1146 Forethought Future Cup Elimination Round Tutorial
CF1146 Forethought Future Cup Elimination Round Tutorial 叮,守夜冠军卡 https://codeforces.com/blog/entry/6 ...
- Codeforces Round #517 (Div. 2, based on Technocup 2019 Elimination Round 2)
Codeforces Round #517 (Div. 2, based on Technocup 2019 Elimination Round 2) #include <bits/stdc++ ...
- Codeforces Round #596 (Div. 2, based on Technocup 2020 Elimination Round 2)
A - Forgetting Things 题意:给 \(a,b\) 两个数字的开头数字(1~9),求使得等式 \(a=b-1\) 成立的一组 \(a,b\) ,无解输出-1. 题解:很显然只有 \( ...
- Codeforces Round #380 (Div. 1, Rated, Based on Technocup 2017 - Elimination Round 2)
http://codeforces.com/contest/737 A: 题目大意: 有n辆车,每辆车有一个价钱ci和油箱容量vi.在x轴上,起点为0,终点为s,中途有k个加油站,坐标分别是pi,到每 ...
- Codeforces Round #380 (Div. 2, Rated, Based on Technocup 2017 - Elimination Round 2) D. Sea Battle 模拟
D. Sea Battle time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) B. Verse Pattern 水题
B. Verse Pattern 题目连接: http://codeforces.com/contest/722/problem/B Description You are given a text ...
- CROC 2016 - Elimination Round (Rated Unofficial Edition) E - Intellectual Inquiry dp
E - Intellectual Inquiry 思路:我自己YY了一个算本质不同子序列的方法, 发现和网上都不一样. 我们从每个点出发向其后面第一个a, b, c, d ...连一条边,那么总的不同 ...
- 8VC Venture Cup 2016 - Elimination Round D. Jerry's Protest 暴力
D. Jerry's Protest 题目连接: http://www.codeforces.com/contest/626/problem/D Description Andrew and Jerr ...
随机推荐
- CAD绘制一个直径标注(com接口VB语言)
主要用到函数说明: _DMxDrawX::DrawDimDiametric 绘制一个直径标注.详细说明如下: 参数 说明 DOUBLE dChordPointX 在被标注的曲线上的第一个点X值 DOU ...
- JavaFX桌面应用开发-鼠标事件和键盘事件
鼠标相关事件的操作初始代码 package application; import javafx.application.Application;import javafx.event.ActionE ...
- Asp.Mvc 常用
url转义 var address = "http://www.cnblog.com"; var a22 = Uri.EscapeDataString(address); var ...
- jquery 对 table 的操作
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head><meta ...
- 文本框、评论框原生js
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...
- SSH技术介绍和Xshell公钥远程登陆
SSH简介 传统的网络服务程序,比如FTP,POP,Telnet,本质上都是不安全的,因为它们在网络上用明文传送数据.用户账号和用户口令,很容易受到中间人攻击方式的攻击,攻击者会冒充真正的服务器接收用 ...
- 安装RHEL7红帽操作系统
1.单击“开启此虚拟机”启动RHEL 7系统安装. 开启虚拟机 2.通过键盘方向键选择Install Red Hat Enterprise Linux 7.0选项,然后回车,开始安装RHEL7操作系统 ...
- STM32窗口看门狗和独立看门狗的区别,看门狗介绍及代码演示
一.介绍: STM32看门狗分为独立看门狗和窗口看门狗两种,其两者使用调条件如下所示, IWDG和WWDG两者特点如下图所示: 独立看门狗的手册资料: 窗口看门狗的手册资料: ...
- zabbix 配置——bak
1.host 配置 create host Parameter Description Host name 主机名,只允许数字,空格,句号,下划线,非主流符号它不支持.zabbix客户端配置文件中的h ...
- 【 Codeforces Global Round 1 B】Tape
[链接] 我是链接,点我呀:) [题意] x轴上有m个连续的点,从1标号到m. 其中有n个点是特殊点. 让你用k段区间将这n个点覆盖. 要求区间的总长度最小. [题解] 一开始假设我们需要n个胶带(即 ...