「模拟赛」暑期集训CSP提高模拟6(7.23)
题目列表
花间叔祖
题意:
给定一个数组,选择一个大于等于 2 的模数,然后把数组中的数变成
只能操作一次,问操作后最少有几种不同的数。
赛时分析:
开始 5 分钟想到了算
正解:
容易得到答案不是 1 就是 2,若存在一个模数使得
赛时我拿
code:
#include<bits/stdc++.h>
#define mp make_pair
#define ll long long
using namespace std;
const int N = 2e5 + 10;
int n, a[N], Ygcd, cnt, Xgcd;
int b[N];
signed main(){
// freopen("in.in", "r", stdin); freopen("out.out", "w", stdout);
scanf("%d%d%d", &n, &a[1], &a[2]);
Ygcd = __gcd(a[1], a[2]);
for(int i=3; i<=n; i++){
scanf("%d", &a[i]);
Ygcd = __gcd(Ygcd, a[i]);
}
if(Ygcd != 1){
puts("1"); return 0;
}
sort(a+1, a+1+n);
for(int i=2; i<=n; i++){
b[++cnt] = a[i] - a[1];
}
Xgcd = __gcd(b[1], b[2]);
for(int i=2; i<=cnt; i++){
Xgcd = __gcd(Xgcd, b[i]);
}
if(Xgcd != 1) puts("1");
else puts("2");
return 0;
}
合并 r
题意:
有
Delov 一口吃掉了美味值之和为
两种方案不同,则存在
正解:
原题
我们这样考虑,
就是说,当前如果凑成了
那么我们只需两种操作,加一与除二,加一代表多选了一个数(初始为
即
初始化
code:
#include<bits/stdc++.h>
using namespace std;
const int N = 5e3 + 10;
const int p = 998244353;
int n, k;
int f[N][N];
int main(){
// freopen("in.in", "r", stdin); freopen("out.out", "w", stdout);
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin>>n>>k;
f[0][0] = 1;
for(int i=1; i<=n; i++){
for(int j=i; j>=1; j--){
f[i][j] = f[i-1][j-1];
if(j * 2 <= i) f[i][j] += f[i][j*2];
f[i][j] %= p;
}
}
cout<<f[n][k];
return 0;
}
回收波特:
题意:
Delov 不和 npy、 们玩了,这回他和他的波特们一起玩。
他和他的
Delov 只有一个控制所有波特的遥控器,所以每次他会给出一个参数
在发送了
你能帮帮他吗?
赛时分析:
一开始一眼就觉得会了,二分思路,时间复杂度正确,然后大喊一句“正解”开打,打了一半二分发现假了。。。于是就先按暴力 if(n*m<=200000000)
然后跟暴力代码,否则跟玄学复杂度代码,最终
正解:
(复制的下发题解思路较简单)
官方题解写的很棒,但是是英语,英语好的/使用翻译的同学可以移步
粘个官方的图
注意到值域有限,考虑对值域内所有数处理出答案
观察一次操作过后,一部分超过原点,一部分到达原点,一部分没过原点,
到达的不用管而超过的部分,后续操作和关于原点对称的位置的操作一模一样,于是可以合并
每次将正半轴负半轴较短的一截与另一边合并起来
这样每个点只会操作
code:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int n, m, vis[N], ans[N];
int x[N], d[N];
std::vector<int>v[N], G;
void dfs(int x, int flag){
for(auto y : v[x]){
vis[y] = vis[x], ans[y] = -1.0 * flag * ans[x];
dfs(y, flag);
}
}
int main(){
// freopen("in.in", "r", stdin); freopen("out.out", "w", stdout);
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin>>n>>m;
for(int i=1; i<=n; i++) cin>>x[i];
for(int i=1; i<=m; i++) cin>>d[i];
int l = 1, r = N - 10, pos = 0, f = 1;//f=1:0 in the left
for(int i=1; i<=m; i++){
int D = d[i];
pos += f * D; // now 0's position
if(pos > r) f = -1;
else if(pos < l) f = 1;
else{
vis[pos] = true, ans[pos] = i;
G.push_back(pos);
int lnum = pos - l, rnum = r - pos;
if(lnum > rnum){
for(int j=1; j<=r-pos; j++) //connect the side
v[pos-j].push_back(pos+j);
r = pos - 1, f = -1;
}
else{
for(int j=1; j<=pos-l; j++)
v[pos+j].push_back(pos-j);
l = pos + 1, f = 1;
}
}
}
for(int i=l; i<=r; i++){
ans[i] = i - pos;
dfs(i, 1);
}
for(int i : G) dfs(i, -1);
for(int i=1; i<=n; i++){
if(vis[x[i]]) printf("Yes");
else printf("No");
printf(" %d\n", ans[x[i]]);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】