2024CCPC郑州邀请赛(组队VP)
B. 扫雷 1
面:
T0xel 喜欢玩扫雷,但是他玩的扫雷游戏有名为“地雷探测器”的特殊道具。
具体来说,T0xel 会进行
现在 T0xel 想知道,在这
输入:
第一行,一个正整数
第二行,
输出:
一行,一个非负整数,表示答案。
样例:
1:
6
3 2 5 3 4
——————————
2
2:
5
6 3 3 4 2
——————————
2
3:
5
7 6 5 9 8
——————————
0
思路:
本题由队友编写
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node{
ll x;
ll num;
bool operator < (const node& a)const{
return x<a.x;
}
};
priority_queue<node> q;
int main(){
int n;
scanf("%d",&n);
ll cnt=0;
ll sum=0;
for(int i=1;i<=n;i++){
sum++;
ll x;
scanf("%lld",&x);
while(!q.empty()&&x<=q.top().x){
sum=sum+(q.top().x*q.top().num);
q.pop();
}
ll t=sum/x;
if(t>0){
q.push({x,t});
}
sum-=t*x;
}
while(!q.empty()){
cnt+=q.top().num;
q.pop();
}
printf("%lld",cnt);
return 0;
}
D. 距离之比
题面:
对于
而
现在给出平面上互不重合的
输入:
第一行,一个正整数
对于每组数据:
- 第一行,一个正整数
,表示平面上的点数。 - 接下来
行,每行两个整数 ,表示点 。
保证对于单个测试点有
输出:
对于每组数据:输出一行,一个实数,表示点对之间曼哈顿距离与欧几里得距离之比的最大值。当你
的答案与标准答案的相对误差或绝对误差不超过
样例:
2
2
0 0
0 1
3
1 1
2 3
5
1.000000000000
1.371988681140
思路:
道题可以用等式变形得出,当两个点的x绝对差与y绝对差越接近,则题目中要求式子值越大。
但是不能直接取最小的,必须得每个扫描一遍。怎么优化?直接在(-1e9,1e9)做个斜率为1的直线,(-1e9,-1e9)做个斜率为-1的直线。然后对这两个直线取个距离分别排序,然后分别计算两个相邻数的
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"// 交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans % mod * (x % mod) % mod;
}
x = x % mod * (x % mod) % mod;
y >>= 1;
}
return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
struct s
{
ll x,y;
ll dis1;
ll dis2;
}p[350000];
bool cmp1(s x, s y)
{
return x.dis1<y.dis1;
}
bool cmp2(s x, s y)
{
return x.dis2<y.dis2;
}
int main()
{
fio();
ll t;
cin>>t;
while(t--)
{
ll n;
cin>>n;
for(ll i=1;i<=n;i++)
{
cin>>p[i].x>>p[i].y;
p[i].dis1=abs(p[i].x-p[i].y+2e9+2);
p[i].dis2=abs(p[i].x+p[i].y+2e9+2);
}
sort(p+1,p+1+n,cmp1);
double ans=0;
for(ll i=1;i<=n-1;i++)
{
double u=(abs(p[i].x-p[i+1].x)+abs(p[i].y-p[i+1].y));
double ku=fabs(sqrt((p[i].x-p[i+1].x)*(p[i].x-p[i+1].x)+(p[i].y-p[i+1].y)*(p[i].y-p[i+1].y)));
ans=max(ans,u/ku);
}
sort(p+1,p+1+n,cmp2);
for(ll i=1;i<=n-1;i++)
{
double u=(abs(p[i].x-p[i+1].x)+abs(p[i].y-p[i+1].y));
double ku=fabs(sqrt((p[i].x-p[i+1].x)*(p[i].x-p[i+1].x)+(p[i].y-p[i+1].y)*(p[i].y-p[i+1].y)));
ans=max(ans,u/ku);
}
printf("%.12lf\n",ans);
}
}
F. 优秀字符串
题面:
小A认为,一个字符串
的长度 恰好为 5; 的第三个字符与第五个字符相同; 的前四个字符互不相同。
例如 "henan" 是优秀字符串,但 "query"、"problem"、"queue" 不是,因为:
- "query" 的第三个字符为 'e',而第五个字符为 'y';
- "problem" 的长度不为 5;
- "queue" 的前四个字符中 'u' 出现了两次。
现在,小A有
输入:
第一行,一个正整数
接下来
输出:
一行,一个整数,表示给定字符串中优秀字符串的数量。
样例:
4
henan
query
problem
queue
1
思路:
签到题,首先看size,然后判断地第3个字符和第5个字符是否相等。最后map遍历一遍看有没重复即可
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"// 交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
const ll p=rnd()%mod;
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans % mod * (x % mod) % mod;
}
x = x % mod * (x % mod) % mod;
y >>= 1;
}
return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
int main()
{
fio();
ll t;
cin>>t;
ll ans=0;
while(t--)
{
string f;
cin>>f;
if(f.size()==5&&f[2]==f[4])
{
map<char,ll>q;
ll pd=0;
for(ll i=0;i<=3;i++)
{
q[f[i]]++;
if(q[f[i]]>=2)
pd=1;
}
if(pd==0)
ans++;
}
}
cout<<ans<<endl;
}
H.随机栈
题面:
Toxel获得了一个随机的“栈”。这个栈可被视为一个多重集
Toxel正在对这个集合做一些操作。集合初始时为空,它总共进行了
由于答案可能不是整数,为了方便计算,你只需要求出这个值对 998244353 取模的结果。
输入:
第一行包含一个整数
第二行包含
输出:
输出一行一个整数,表示答案对 998 244 353 取模的结果。
样例:
1:
2
1 2 -1 -1
————————
499122177
2:
3
1 2 -1 -1 1 -1
————————
0
3:
4
1 -1 2 -1 3 -1 4 -1
————————
1
思路:
队友写的
#include<bits/stdc++.h>
using namespace std;
//60
typedef long long ll;
const int N=1000050;
const ll mod=998244353;
ll qm(ll a,ll x){
ll ans=1;
while(x){
if(x%2){
ans=(ans%mod)*(a%mod)%mod;
}
a=(a%mod)*(a%mod)%mod;
x/=2;
}
return ans%mod;
}
void mul(ll a,ll b,ll& ans){//a/b*ans;
ans=(ans%mod*a%mod)%mod;
ll fenmu=qm(b,mod-2);
ans=(ans%mod*fenmu%mod)%mod;
}
int goal[N];
int a[N];
map<ll,ll>mp;
int main(){
int n,m=0;
scanf("%d",&n);
for(int i=1;i<=2*n;i++){
scanf("%lld",&a[i]);
if(a[i]>=0){
goal[++m]=a[i];
}
}
sort(goal+1,goal+1+n);
ll ans=1;
ll cnt=0;//个数
ll now=0;
for(int i=1;i<=2*n;i++){
if(a[i]>=0){
mp[a[i]]++;
cnt++;
}else{
ll has=mp[(goal[++now])];
if(has==0){
ans=0;break;
}
mul(has,cnt,ans);
mp[goal[now]]--;
cnt--;
}
if(ans==0){
break;
}
}
printf("%lld",ans%mod);
return 0;
}
/*
2
1 2 -1 -1
3
1 2 2 -1 -1 -1
*/
J. 排列与合数
题面:
小A在2023年河南省CCPC大学生程序设计竞赛的赛场上遇到了一道名为“排列与质数”的题目。与大多数选手一样,小A并没能在赛场上解决这个棘手的题目。比赛结束后,小A想到了一个与之相关的题目:排列与合数,可是小A仍然没有能力解决。这个名为“排列与合数”的题目是这样的:
给定一个有且仅有5位,且各个数位互不相同的十进制正整数
例如,当
一个正整数是合数,当且仅当它可以分解为两个不小于2的整数的乘积。
现在,小A带着他的题目来到赛场上求助。你能帮助小A解决这个题目吗?
输入:
第一行,一个正整数
对于每组数据:
- 一行,一个正整数
,保证 的各个数位互不相同。
输出:
对于每组数据:
输出一行,一个整数。若能重新排列
样例:
5
12345
12345
12345
12345
13579
————————
12345
54321
13524
45123
97531
思路:
先用欧拉筛先把质数筛出来,然后暴枚所有可能,最后判断下是否为合数就行了,注意数大于0才能进行下一层递归
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll int
#define lowbit(x) (x & -x)
#define endl "\n"// 交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
const ll p=rnd()%mod;
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans % mod * (x % mod) % mod;
}
x = x % mod * (x % mod) % mod;
y >>= 1;
}
return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
bool st[150000];
bool fk[150000];
ll z[150000];
ll gs=0;
void ola(ll x)
{
for(ll i=2;i<=x;i++)
{
if(!st[i]){
gs+=1;
z[gs]=i,fk[i]=1;
}
for(ll j=1;z[j]<=x/i;j++)
{
st[z[j]*i]=1;
if(i%z[j]==0)
break;
}
}
}
ll a[150000];
bool vi[15000];
ll ans;
ll pd=0;
void dfs(ll x,ll sd)
{
if(pd)
return ;
if(sd==6)
{
if(!fk[x]==1)
ans=x,pd=1;
return ;
}
for(ll i=1;i<=5;i++)
{
if(vi[i]==0)
{
vi[i]=1;
ll u=x*10+a[i];
if(u>0)
{
dfs(u,sd+1);
}
if(pd)return;
vi[i]=0;
}
}
return ;
}
int main()
{
fio();
ll t;
cin>>t;
ola(100000);
while(t--)
{
pd=0;
string f;
cin>>f;
ans=0;
for(ll i=1;i<=5;i++)
{
a[i]=f[i-1]-'0';
vi[i]=0;
ans=ans*10+a[i];
}
dfs(0,1);
if(pd==0)cout<<-1<<endl;
else
cout<<ans<<endl;
}
return 0;
}
k.树上问题
题面:
378QAQ有一棵由
378QAQ认为一个节点是美丽节点,当且仅当该节点作为根时,对于除根节点以外的所有节点,其点权都不小于其父亲节点的点权的
请你计算出有多少个节点是美丽节点。
输入:
第一行包含一个正整数
对于每组数据:
- 第一行包含一个正整数
,表示节点数量。 - 第二行包含
个正整数 ,表示编号为 的节点点权。 - 之后
行,每行包含两个正整数 ,表示无根树中存在一条连接节点 和节点 的边。
保证单个测试点中所有数据的
输出:
对于每组数据,输出一个非负整数,代表美丽节点的数量。
样例:
3
3
1 2 3
1 2
2 3
5
3 2 2 2 1
1 2
3 1
4 1
1 5
8
699 673 592 276 600 343 369 374
7 6
8 5
4 6
7 1
7 2
1 8
4
3
1
7
思路:
这题为根的转移变化,首先以1为根构建出基本的树结构,然后进行根动态变化就好了,用vis标记表示这个点是否为不符合点,被标记了就是不符合的,然后用cnt统计不符合标记的个数。每次转移储存原状态,并进行状态更新,回溯进行状态还原,这样可以保证树总是以现在这个节点为根.
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll int
#define lowbit(x) (x & -x)
#define endl "\n"// 交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
const ll p=rnd()%mod;
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans % mod * (x % mod) % mod;
}
x = x % mod * (x % mod) % mod;
y >>= 1;
}
return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
ll a[250000];
vector<ll>g[260000];
bool vis[250000];
ll cnt=0;
void dfs(ll x,ll fa)
{
if(a[x]*2<a[fa])
vis[x]=1,cnt++;
for(auto j:g[x])
{
if(j==fa)continue;
dfs(j,x);
}
return ;
}
ll ans=0;
void df(ll x,ll fa)
{
ll u=vis[fa],k=vis[x];
if(x!=1)
{
if(k==1)
cnt--,vis[x]=0;
if(u==1)
cnt--,vis[fa]=0;
if(a[fa]*2<a[x])
{
cnt++,vis[fa]=1;
}
if(cnt==0)
ans++;
}
for(auto j:g[x])
{
if(j==fa)continue;
df(j,x);
}
if(u==0&&vis[fa]==1)
cnt--,vis[fa]=0;
if(u==1&&vis[fa]==0)
cnt++,vis[fa]=1;
if(k==0&&vis[x]==1)
cnt--,vis[x]=0;
if(k==1&&vis[x]==0)
cnt++,vis[x]=1;
return ;
}
int main()
{
fio();
ll t;
cin>>t;
while(t--)
{
ans=0;
a[0]=0;
ll n;
cin>>n;
cnt=0;
for(ll i=1;i<=n;i++)cin>>a[i],g[i].clear(),vis[i]=0;
for(ll i=1;i<n;i++)
{
ll l,r;
cin>>l>>r;
g[l].push_back(r);
swap(l,r);
g[l].push_back(r);
}
dfs(1,0);
if(cnt==0)
ans++;
df(1,0);
cout<<ans<<endl;
}
}
L.Toxel 与 PCPC II
题面:
Toxel正在参加 PCPC (Pokémon Center Programming Contest) 比赛。它写的一段代码中有不少bug,正在调试。这份代码总共有
Toxel会进行多次调试。每次调试时,Toxel可以任选一个
PCPC的赛场争分夺秒。请你帮Toxel计算一下,它最短需要多少秒才能完成debug,修复整个代码中的所有漏洞?
输入:
第一行包含两个整数 ( n, m ) ( (1 \leq m \leq n \leq 2 \times 10^5) )。
第二行包含 ( m ) 个整数 ( a_1, a_2, \ldots, a_m ) ( (1 \leq a_1 < a_2 < \ldots < a_m \leq n) ),表示代码中所有有 bug 的行编号。
输出:
输出一行一个整数,表示答案。
样例:
1:
3 2
1 3
——————
6
2:
1 1
1
——————
2
3:
20 20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
——————
221
思路:
这题队友写的
#include<bits/stdc++.h>
using namespace std;
//60
typedef long long ll;
const int N=200005;
int n,m;
ll dp[N]={0};
ll a[N]={0};
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%lld",&a[i]);
}
a[0]=a[1];
for(int i=1;i<=m;i++){
dp[i]=1e18;
}
dp[0]=0;
for(int i=1;i<=m;i++){
for(int j=0;i-j>=1&&j<=60;j++){//j个一起
dp[i]=min(dp[i],dp[i-j-1]+(j+1)*(j+1)*(j+1)*(j+1)+a[i]);
}
}
printf("%lld\n",dp[m]);
return 0;
}
/*
20 20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
*/
M.有效算法
题面:
给出长度为
- 将
变成满足 的任意整数 。
请你求出最小的非负整数
输入:
第一行包含一个正整数
对于每组数据:
- 第一行包含一个正整数
。 - 第二行包含
个正整数 。 - 第三行包含
个正整数 。
保证单个测试点中所有数据的
输出:
对于每组数据:
输出一行一个整数,表示答案。
样例:
2
4
8 3 3 5
1 2 3 2
5
4 3 4 5 6
3 1 3 1 1
——————
2
2
思路:
显然K越大,答案肯定有,而k越小x的范围越小,所以就去二分k,然后再取算出x的范围,如果x有解r=mid,否则l=mid+1,最后即可得到答案,推荐范围开大点,防止错误
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll long long
#define lowbit(x) (x & -x)
#define endl "\n"// 交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
const ll p=rnd()%mod;
ll ksm(ll x, ll y)
{
ll ans = 1;
while (y)
{
if (y & 1)
{
ans = ans % mod * (x % mod) % mod;
}
x = x % mod * (x % mod) % mod;
y >>= 1;
}
return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
if (y == 0)
return x;
else
return gcd(y, x % y);
}
void fio()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
ll a[550000];
ll b[550000];
int main()
{
fio();
ll t;
cin>>t;
while(t--)
{
ll n;
cin>>n;
for(ll i=1;i<=n;i++)cin>>a[i];
for(ll i=1;i<=n;i++)cin>>b[i];
ll l=0,r=1e9;
while(l<r)
{
ll z=-2e18,y=2e18;
ll mid=(l+r)>>1;
for(ll i=1;i<=n;i++)
{
ll u1=-mid*b[i];
ll u2=mid*b[i];
z=max(z,a[i]+u1);
y=min(y,u2+a[i]);
}
if(z<=y)
r=mid;
else l=mid+1;
}
cout<<r<<endl;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现