The 16th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple (Mirror)
B题
思路
因为
\[
x=\sum\limits_{k=1}^{n}ka_k\\
y=\sum\limits_{k=1}^{n}ka_{k}^{2}
\]
我们设交换前和交换后的这两个等式的值设为\(x_1,y_1,x_2,y_2\),现在我们开始愉快的推公式
\[
\begin{aligned}
&x_1-x_2=(i-j)(a_i-a_j)&\\
&y_1-y_2=(i-j)(a_i^2-a_j^2)&\\
\Rightarrow &\frac{y1-y2}{x_1-x_2}=a_i-a_j&(1)\\
&j=i-\frac{x_1-x_2}{a_i-a_j}&(2)
\end{aligned}
\]
然后我们枚举每一个\(i\),根据\((1)(2)\)计算出\(a_j\)和\(j\)然后判断现在在\(j\)这个位置上的值是不是你算出来的这个\(a_j\),是就答案加一否则答案不变。
#include <bits/stdc++.h>
using namespace std;
#define bug printf("********\n")
#define FIN freopen("in.txt","r",stdin)
#define debug(x) cout<<"["<<x<<"]"<<endl
typedef long long LL;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
int t, n;
LL x, y, b[maxn], cnt[maxn];
int main() {
#ifndef ONLINE_JUDGE
FIN;
#endif // ONLINE_JUDGE
scanf("%d", &t);
while(t--) {
scanf("%d%lld%lld", &n, &x, &y);
LL xx = 0, yy = 0;
for(int i = 1; i <= n; ++i) {
scanf("%lld", &b[i]);
cnt[b[i]]++;
xx += b[i] * i;
yy += b[i] * b[i] * i;
}
LL dx = xx - x, dy = yy - y;
LL ans = 0;
if(dx == 0 && dy == 0) {
for(int i = 1; i <= n; ++i) {
ans += cnt[b[i]] - 1;
cnt[b[i]]--;
}
printf("%lld\n", ans);
for(int i = 1; i <= n; ++i) cnt[b[i]] = 0;
continue;
}
if(dx == 0 || dy == 0 || dy % dx) {
printf("0\n");
for(int i = 1; i <= n; ++i) cnt[b[i]] = 0;
continue;
}
LL num = dy / dx;
for(int i = 1; i <= n; ++i) {
if(num - b[i] <= 0) continue;
LL num1 = b[i], num2 = num - num1;
if(num1 == num2 || dx % (num1 - num2) != 0) continue;
LL pos = i - dx / (num1 - num2);
if(pos >= 1 && pos < i && b[pos] == num2) ans++;
}
printf("%lld\n", ans);
for(int i = 1; i <= n; ++i) cnt[b[i]] = 0;
}
return 0;
}
E题
思路
线段树,对于每个点它是否修改取决于在原序列是否有比它大的数或者比它大的数进行过操作。
代码实现如下
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> piL;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("in","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0)
const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
int t, n;
int a[maxn], num[maxn];
vector<int> v;
struct node {
int l, r, sum;
}segtree[maxn<<2];
int getid(int x) {
return lower_bound(v.begin(), v.end(), x) - v.begin() + 1;
}
void push_up(int rt) {
segtree[rt].sum = segtree[lson].sum + segtree[rson].sum;
}
void build(int rt, int l, int r) {
segtree[rt].l = l, segtree[rt].r = r;
segtree[rt].sum = 0;
if(l == r) return;
int mid = (l + r) >> 1;
build(lson, l, mid);
build(rson, mid + 1, r);
}
void update(int rt, int pos) {
if(segtree[rt].l == segtree[rt].r) {
segtree[rt].sum++;
return;
}
int mid = (segtree[rt].l + segtree[rt].r) >> 1;
if(pos <= mid) update(lson, pos);
else update(rson, pos);
push_up(rt);
}
int query(int rt, int l, int r) {
if(segtree[rt].l == l && segtree[rt].r == r) {
return segtree[rt].sum;
}
int mid = (segtree[rt].l + segtree[rt].r) >> 1;
if(r <= mid) return query(lson, l, r);
else if(l > mid) return query(rson, l, r);
else return query(lson, l, mid) + query(rson, mid + 1, r);
}
int main() {
scanf("%d", &t);
while(t--) {
scanf("%d", &n);
v.clear();
priority_queue<pii> q;
for(int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
num[i] = 0;
v.push_back(a[i]);
q.push({a[i], i});
}
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
build(1, 1, v.size() + 1);
for(int i = 1; i <= n; ++i) {
num[i] = query(1, getid(a[i]) + 1, v.size() + 1);
update(1, getid(a[i]));
}
int x;
int ans = 0, las = 0;
build(1, 1, v.size() + 1);
while(!q.empty()) {
int x = q.top().second; q.pop();
if(num[x] || query(1, getid(a[x]) + 1, v.size() + 1)) {
ans++;
update(1, getid(a[x]));
}
}
printf("%d\n", ans);
}
return 0;
}
F题
思路
暴力模拟即可。
代码实现如下
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> piL;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("in","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0)
const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
int t;
vector<char> v;
char s[105];
set<char> st;
int main() {
scanf("%d", &t);
st.insert({'a', 'e', 'i', 'y', 'o', 'u'});
while(t--) {
scanf("%s", s);
v.clear();
int len = strlen(s), flag = 0;
for(int i = 0; i < len; ++i) {
if(!st.count(s[i])) v.push_back(s[i]), flag = 1;
else if(!flag) v.push_back(s[i]), flag = 1;
}
for(int i = 0; i < (int)v.size(); ++i) {
printf("%c", v[i]);
}
printf("\n");
}
return 0;
}
G题
思路
暴力判断。
代码实现如下
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> piL;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("in","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0)
const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
int t, n;
bool check(int x) {
return x % 7 == 0 && x % 4 != 0;
}
int main() {
scanf("%d", &t);
while(t--) {
scanf("%d", &n);
while(!check(n)) n++;
printf("%d\n", n);
}
return 0;
}
H题
思路实现如下
暴力枚举每个点删除会对答案的影响,然后对所有情况取最小值。
代码实现如下
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> piL;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("in","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0)
const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
int t, n;
int a[maxn];
int main() {
scanf("%d", &t);
while(t--) {
scanf("%d", &n);
for(int i = 0; i <= n + 1; ++i) {
a[i] = inf;
}
for(int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
int sum = 0;
for(int i = 2; i < n; ++i) {
if(a[i] > a[i-1] && a[i] > a[i+1]) {
sum++;
}
}
int ans = sum;
for(int i = 1; i <= n; ++i) {
int num = 0;
if(a[i] > a[i-1] && a[i] > a[i+1]) {
num++;
if(i >= 2 && a[i-1] > a[i-2] && a[i-1] > a[i+1]) num--;
if(i <= n - 2 && a[i+1] > a[i+2] && a[i+1] > a[i-1]) num--;
} else {
if(i >= 2) {
if(a[i-1] > a[i-2] && a[i-1] > a[i]) num++;
if(a[i-1] > a[i-2] && a[i-1] > a[i+1]) num--;
}
if(i <= n - 2) {
if(a[i+1] > a[i] && a[i+1] > a[i+2]) num++;
if(a[i+1] > a[i+2] && a[i+1] > a[i-1]) num--;
}
}
ans = min(ans, sum - num);
}
printf("%d\n", ans);
}
return 0;
}
I题
思路
从\(4\)的倍数往上每四个数异或后都会是\(0\),因此对\(a\)和\(b\)枚举到在\([a,b]\)间离它们最近的\(4\)的倍数,然后把这中间的数进行异或即可。
代码实现如下
import java.util.*;
import java.math.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
while(t-- != 0) {
BigInteger a = sc.nextBigInteger();
BigInteger b = sc.nextBigInteger();
int ans = 0;
while(!a.mod(BigInteger.valueOf(3)).equals(BigInteger.ZERO) && a.compareTo(b) <= 0) {
ans++;
a = a.add(BigInteger.ONE);
}
while(!b.mod(BigInteger.valueOf(3)).equals(BigInteger.ZERO) && b.compareTo(a) > 0) {
ans++;
b = b.subtract(BigInteger.ONE);
}
System.out.println(ans % 2);
}
sc.close();
}
}
T = eval(input())
while(T):
T -= 1
a, b = map(int, input().split())
ans = 0
while(a % 3 != 0 and a <= b):
ans += 1
a += 1
while(b % 3 != 0 and b > a):
ans += 1
b -= 1
print(ans % 2)
J题
思路
我们先用并查集来维护联通块,为了保持字典序最小,我们从小到大将每个联通块取一个数放进优先队列,然后跑\(bfs\)即可。
代码实现如下
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> piL;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("in","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0)
const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
int t, n, m, x, y;
vector<int> G[maxn];
priority_queue<int> q;
int fa[maxn], vis[maxn], pp[maxn];
int fi(int x) {
return fa[x] == x ? x : fa[x] = fi(fa[x]);
}
void mer(int x, int y) {
int p1 = fi(x), p2 = fi(y);
if(p1 == p2) return;
if(p1 < p2) {
fa[p2] = p1;
} else {
fa[p1] = p2;
}
}
int main() {
#ifndef ONLINE_JUDGE
FIN;
#endif
scanf("%d", &t);
while(t--) {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i) {
fa[i] = i;
pp[i] = vis[i] = 0;
G[i].clear();
}
for(int i = 1; i <= m; ++i) {
scanf("%d%d", &x, &y);
G[x].push_back(y);
G[y].push_back(x);
mer(x, y);
}
while(!q.empty()) q.pop();
for(int i = 1; i <= n; ++i) {
int p = fi(i);
if(pp[p]) continue;
q.push(-p);
pp[p] = 1;
}
printf("%d\n", (int)q.size());
int flag = 0;
while(!q.empty()) {
int u = -q.top(); q.pop();
if(vis[u]) continue;
if(flag) printf(" ");
flag = 1;
printf("%d", u);
vis[u] = 1;
for(int i = 0; i < (int)G[u].size(); ++i) {
int v = G[u][i];
if(vis[v]) continue;
q.push(-v);
}
}
printf("\n");
}
return 0;
}
K题
思路
这题我们分两种情况进行分析:
\(1.s==t:\)这种情况我们可以用\(manacher\)将\(s\)中的所有回文子串数计算出来;
\(2.s!=t:\)这种情况我们先找到\(s\)中与\(t\)不相同的最左最右的端点,然后判断这一段能否翻转使得\(s==t\),不能答案就是\(0\),否则就枚举这个区间能够向外延伸多远。
代码实现如下
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> piL;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("in.txt","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0)
const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
int t, n;
LL x, y, xx, yy, b[maxn];
map<LL, int> cnt;
int main() {
#ifndef ONLINE_JUDGE
FIN;
#endif
scanf("%d", &t);
while(t--) {
scanf("%d%lld%lld", &n, &x, &y);
xx = yy = 0;
cnt.clear();
for(int i = 1; i <= n; ++i) {
scanf("%lld", &b[i]);
xx += b[i] * i;
yy += b[i] * b[i] * i;
cnt[b[i]]++;
}
LL ans = 0;
if(x != xx) {
if((y - yy) % (x - xx) != 0) {
printf("0\n");
continue;
}
LL num = (y - yy) / (x - xx);
for(int i = 1; i <= n; ++i) {
LL num1 = b[i], num2 = num - b[i];
if(num1 == num2) continue;
LL tmp = num1 - num2;
if((x - xx) % tmp != 0) continue;
LL j = (x - xx) / tmp;
LL pos = i + j;
if(pos >= 1 && pos <= n && b[pos] == num2) ans++;
}
printf("%lld\n", ans/2);
} else {
if(y == yy) {
for(int i = 1; i <= n; ++i) {
ans += cnt[b[i]] - 1;
cnt[b[i]]--;
}
}
printf("%lld\n", ans);
}
}
return 0;
}
The 16th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple (Mirror)的更多相关文章
- The 15th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple - L Doki Doki Literature Club
Doki Doki Literature Club Time Limit: 1 Second Memory Limit: 65536 KB Doki Doki Literature Club ...
- 2018浙江省赛(ACM) The 15th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple
我是铁牌选手 这次比赛非常得爆炸,可以说体验极差,是这辈子自己最脑残的事情之一. 天时,地利,人和一样没有,而且自己早早地就想好了甩锅的套路. 按理说不开K就不会这么惨了啊,而且自己也是毒,不知道段错 ...
- The 16th Zhejiang Provincial Collegiate Programming Contest Sponsored E.Sequence in the Pocket(思维题)
传送门 题意: 给出一个序列,你可以将任意一个数移到最前面: 求最少需要移动多少次,可以是此序列变成非递减序列: 思路: 定义 (ai,aj) 为逆序对 ( i < j , ai > aj ...
- The 16th Zhejiang Provincial Collegiate Programming Contest Sponsored(E F G H I)
http://acm.zju.edu.cn/onlinejudge/showContestProblems.do?contestId=392 E:Sequence in the Pocket 思路:从 ...
- The 14th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple - F 贪心+二分
Heap Partition Time Limit: 2 Seconds Memory Limit: 65536 KB Special Judge A sequence S = { ...
- The 14th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple - C 暴力 STL
What Kind of Friends Are You? Time Limit: 1 Second Memory Limit: 65536 KB Japari Park is a larg ...
- The 15th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple - M Lucky 7
Lucky 7 Time Limit: 1 Second Memory Limit: 65536 KB BaoBao has just found a positive integer se ...
- The 15th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple - J CONTINUE...?
CONTINUE...? Time Limit: 1 Second Memory Limit: 65536 KB Special Judge DreamGrid has clas ...
- The 15th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple - B King of Karaoke
King of Karaoke Time Limit: 1 Second Memory Limit: 65536 KB It's Karaoke time! DreamGrid is per ...
随机推荐
- 打包工具Gradle
Gradle Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化建构工具.它使用一种基于Groovy的特定领域语言来声明项目设置,而不是传统的XML.当前其支持的语言 ...
- 搭建基于docker 的redis分布式集群在docker for windows
https://blog.csdn.net/xielinrui123/article/details/85104446 首先在docker中下载使用 docker pull redis:3.0.7do ...
- python:实现几种排序算法
冒泡排序 比较相邻两个字符,如果左边大于右边,则交换位置,遍历一遍字符后,则最大的肯定在最右边:继续循环处理剩下的字符(最右边的不用再比较了,已经最大了) 代码实现: def BubbleSort(s ...
- Java IO 与 NIO 服务器&客户端通信小栗子
本篇包含了入门小栗子以及一些问题的思考 BIO package com.demo.bio; import java.io.*; import java.net.ServerSocket; import ...
- js获取当前时间,格式YYYY-MM-DD
//获取当前时间,格式YYYY-MM-DD function getNowFormatDate() { var date = new Date(); var seperator1 = "-& ...
- Scratch学习中需要注意的地方,学习Scratch时需要注意的地方
在所有的编程工具中,Scratch是比较简单的,适合孩子学习锻炼,也是信息学奥赛的常见项目.通常Scratch学习流程是,先掌握程序相关模块,并且了解各个模块的功能使用,然后通过项目的编写和练习,不断 ...
- day10——动态参数、函数注释、名称空间、函数的嵌套、global及nonlocal
day10 三元运算符: 变量 = 条件成立的结果 条件判断 条件不成立的结果 补充: # lst = [12,23,3,4,5,6] # def func(*args): # print(*args ...
- C_局部变量&全局变量
2018-5-9 Writen By Stephen.Yu 一.定义 1. 局部变量:在函数中定义的变量 2. 全局变量:在所有函数体之外定义 定义(Definition):声明并分配内存;未分 ...
- CLRS10.1-7练习 - 用双队列实现栈
算法中心思想: 始终向非空队列进行入队操作 初始化时两个队列都为空,我们对q1进行入队操作 入栈: 只需执行其中一个队列入队操作即可, 具体操作哪一个队列,用一个标记变量标记 出栈流程图 代码实现 p ...
- 【Rust】使用cargo创建项目及cargo源的替换
---------------------------------参考文档------------------------------- https://rustlang-cn.org/office/ ...