打卡信奥刷题(3349)用C++实现信奥题 P9509 『STA - R3』Aulvwc
P9509 『STA - R3』Aulvwc
题目背景
统计学是一门古老而迷人的学科。
传说早在若干年前,一位名为惠普的神灵来到地球,发现了人类——另一种有智慧的物种……
已加入 Hack 数据,位于 Subtask 5,不计分。
题目描述
定义一个序列 {an}\{a_n\}{an} 是分部平均的,当且仅当存在一个 {1,2,⋯ ,n}\{1,2,\cdots,n\}{1,2,⋯,n} 的划分 S1,S2,⋯ ,SkS_1,S_2,\cdots,S_kS1,S2,⋯,Sk(其中 k>1k>1k>1),满足对于每个整数 1≤i≤k1\le i\le k1≤i≤k,序列 {a}\{a\}{a} 中以 SiS_iSi 为下标的元素之平均数都是相等的整数。
现在,给定序列 {an}\{a_n\}{an},问它是否是分部平均的。
如果你对于一些定义不很清楚,可以查阅最后的「提示」部分。
输入格式
第一行,一个正整数 qqq,表示询问组数。
对于每组询问,第一行一个正整数 nnn,描述序列长度。第二行 nnn 个整数,表示序列 {an}\{a_n\}{an}。
输出格式
qqq 行,对于每组询问,如果序列是分部平均的,则输出 Yes,否则输出 No。
输入输出样例 #1
输入 #1
4
5
1 1 1 1 1
5
1 2 3 4 5
5
1 1 1 1 6
5
-1 0 1 0 1
输出 #1
Yes
Yes
No
No
说明/提示
提示
一个集合 SSS 的划分定义为一组集合 U1,U2,⋯ ,UkU_1,U_2,\cdots,U_kU1,U2,⋯,Uk,满足:
- 对于所有 i≠ji\neq ji=j,有 Ui∩Uj=∅U_i\cap U_j=\varnothingUi∩Uj=∅。
- U1∪U2∪⋯∪Uk=SU_1\cup U_2\cup\cdots\cup U_k=SU1∪U2∪⋯∪Uk=S。
一个序列 {xn}\{x_n\}{xn} 的平均数定义为:
xˉ=x1+x2+⋯+xnn=1n∑i=1nxi\bar x=\dfrac{x_1+x_2+\cdots+x_n}{n}=\dfrac 1n\sum_{i=1}^nx_ixˉ=nx1+x2+⋯+xn=n1i=1∑nxi
样例解释
第一组数据的一种划分方案:{1},{2},{3},{4},{5}\{1\},\{2\},\{3\},\{4\},\{5\}{1},{2},{3},{4},{5}。
第二组数据的一种划分方案:{1,5},{2,4},{3}\{1,5\},\{2,4\},\{3\}{1,5},{2,4},{3}。
注意:划分方案所提供的集合是下标集合。
数据范围
本题采用捆绑测试及子任务依赖。
Subtaskn≤分值特殊性质依赖子任务1105210320∑ai=031002514103501, 3 \newcommand{\arraystretch}{1.5} \begin{array}{c|c|c|c|c}\hline\hline \textbf{Subtask} & \bm{n}\le & \textbf{分值} & \textbf{特殊性质}&\textbf{依赖子任务}\\\hline \textsf{1} & 10 & 5 & \\\hline \textsf{2} & 10^3 & 20 & \sum a_i=0 \\\hline \textsf{3} & 100 & 25 & & \sf1\\\hline \textsf{4} & 10^3 & 50 & & \sf1\texttt{,}\ 3\\\hline \end{array} Subtask1234n≤10103100103分值5202550特殊性质∑ai=0依赖子任务11, 3
对于全部数据,1≤q≤101\le q\le 101≤q≤10,2≤n≤1032\le n\le 10^32≤n≤103,∣ai∣≤5×103|a_i|\le 5\times10^3∣ai∣≤5×103。
C++实现
#include <cstdio>
#include <cstring>
using namespace std;
int t,n,a[1007];
short f1[7][1007][2007],g1[7][1007][2007];
int s,p[]={0,1799,1857,1927,1924,1981,1999};//判断的模数
signed main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);s=0;
for(int i=1;i<=n;i++) scanf("%d",&a[i]),s=s+a[i];
if(s%n!=0){
printf("No\n");//没有平均数
continue;
}
s=s/n;
memset(f1,0,sizeof f1);
memset(g1,0,sizeof g1);
for(int i=1;i<=n;i++) a[i]=a[i]-s;//问题转化
for(int k=1;k<=6;k++){
g1[k][0][0]=f1[k][0][0]=1;
for(int i=1;i<=n;i++){
for(int j=0;j<p[k];j++){
f1[k][i][j]=g1[k][i-1][(j-a[i]+p[k]+p[k]+p[k])%p[k]];
g1[k][i][j]=g1[k][i-1][j]+f1[k][i][j];
if(g1[k][i][j]>10000) g1[k][i][j]=10000;//这里显然可以剪去情况
}
}
}
int ans=1;
for(int k=1;k<=6;k++){
ans=ans&&(g1[k][n][0]>=3);//所有模数都要过
}
if(ans) printf("Yes\n");
else printf("No\n");
}
return 0;
}

后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容
更多推荐
所有评论(0)