首页 > 其他分享 >2022.10.5 模拟赛

2022.10.5 模拟赛

时间:2022-10-05 14:56:02浏览次数:89  
标签:g4 g3 g2 g1 int long 2022.10 模拟

T1签到题

题面

Description

给定\(n\)个数,求出这\(n\)个数的一个非空子集,使得这个子集中的数的和能被\(n\)整除,无解输出\(-1\).

Input

第一行为数据组数\(T\)
接下来\(T\)组数据,每组数据第一行为一个正整数\(n\),第二行为\(n\)个用空格分开的数。

Output

对于每一组数据,如果无解输出一行一个整数-1;否则第一行输出一个正整数m,表示子集的大小,然后在第二行输出m个数,分别是这个子集中的数。如果有多种方案,输出任意一种。

Sample Input

1
1
1

Sample Output

1
1

Data Constraint

对于\(30\%\)的数据 \(n\le 20\)
对于\(50\%\)的数据 \(n\le100\)
对于\(70\%\)的数据 \(n\le1000\)
对于\(100\%\)的数据 \(n\le100000,T\le10\)

题解

记\(s\)数组为\(a\)数组的模\(n\)下的前缀和。由抽屉原理,所以\(s_0,s_1,s_2,\cdots,s_n\)中在模\(n\)的前提下必有两个数相等,必有解,所以必有一段连续的\(a\)的和模\(n\)为\(0\)。我们只需要求出两个相同的\(s_i\)和\(s_j\)即可,我的代码时间复杂度为\(\Theta(Tn\log n)\)

code

#include<bits/stdc++.h>
#define rg register
#define fre(x)freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
using namespace std;
typedef long long LL;
typedef long double LD;
typedef double db;
typedef unsigned long long uLL;
const db Pi=acos(-1);
vector<int> ans;
int a[100005],T,n,s[100005],id[100005];
bool cmp(int x,int y){return s[x]<s[y];}
int main(){
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
			s[i]=(s[i-1]+a[i]%n+n)%n;
			id[i]=i;
		}id[++n]=0;
		sort(id+1,id+n+1,cmp);
		for(int i=1;i<n;i++)
		if(s[id[i]]==s[id[i+1]]){
			int l=id[i],r=id[i+1];
			if(l>=r)swap(l,r);
			printf("%d\n",r-l);
			for(int i=l+1;i<=r;i++)
			printf("%d ",a[i]); 
			break;
		}
		putchar(10); 
	}
    return 0;
}

T2邮局选址

题面

Description

在 J 市的一条笔直的公路旁分布着 n 个村庄,每个村庄都有一个唯一的坐标 Xi,任意一对村庄的坐标不同。最近,J 市领导计划在村庄里新建 m 个邮局,而邮局在 n个村庄里的分布情况会影响到居民的便利程度。
设 m 个邮局分别建在 P1,P2,..,Pm 号村庄。每个村庄的村民都会找到与其距离最近的一个邮局,若有多个距离最近的则会任选一个,该村庄的便利度即为该村庄与其最近的邮局的距离,而所有村庄的便利度的和即为总便利度。
严格地讲,总便利度 C定义为Σmin⁡{|Xi-XPj| (1≤j≤m)}
现在,由你来安排邮局的建设位置。请计算最小的 C 是多少。

Input

第一行两个整数 n m
第二行递增的n 个整数,表示 X1..Xn

Output

一行一个整数,表示最小的 C

Sample Input

10 5
1 2 3 6 7 9 11 22 44 50

Sample Output

9

Data Constraint

对于30%的测试数据 n ≤ 10
对于60%的测试数据 n ≤ 50
对于100%的测试数据 1 ≤ n ≤ 300; 1 ≤ m ≤ 30; m ≤ n; 1 ≤ Xi ≤ 10000

Hint

样例解释:建立在坐标为:2 7 22 44 50的位置
每个村庄的便利度分别为:1 0 1 1 0 2 4 0 0 0

题解

显然这些点肯定是放在村庄上的,所以动态规划,我们设状态\(f_{i,j}\)为前\(i\)个村庄,放\(j\)个邮局,且第\(i\)个村庄放邮局。方便转移我们预处理出一个数组\(w_{i,j}\)表示在\(i,j\)区间里只在第\(i\)和第\(j\)个村庄修建邮局,\(i\)到\(j\)这几个村庄的便利度是多少,我们可以写出转移方程。

\[f_{i,j}=\min_{0\le k<i}(f_{k,j-1}+w_{k,i}) \]

答案为\(f_{n+1,m+1}\),我在两端分别加了一个邮局,另外预处理即可,时间复杂度为\(\Theta(n^3+n^2m)\)。

code

#include<bits/stdc++.h>
#define rg register
#define fre(x)freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
using namespace std;
typedef long long LL;
typedef long double LD;
typedef double db;
typedef unsigned long long uLL;
const db Pi=acos(-1);
LL w[305][305],x[305],f[305][35];
int main(){
	int n,m;scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%lld",&x[i]);
	sort(x+1,x+n+1);
	for(int i=1;i<=n;i++)
	for(int j=1;j<i;j++)
	w[0][i]+=x[i]-x[j];
	for(int i=1;i<=n;i++)
	for(int j=i+1;j<=n;j++)
	w[i][n+1]+=x[j]-x[i];
	for(int i=1;i<=n;i++)
	for(int j=i+1;j<=n;j++)
	for(int k=i+1;k<j;k++)
	w[i][j]+=min(x[k]-x[i],x[j]-x[k]);
	memset(f,27,sizeof(f));f[0][0]=0;
	for(int i=1;i<=n+1;i++)
	for(int j=1;j<=m+1;j++){
		for(int k=0;k<i;k++)
		f[i][j]=min(f[i][j],f[k][j-1]+w[k][i]);
	}
	printf("%lld",f[n+1][m+1]);
    return 0;
}

T3分数

题面

Description

在一门叫做计算机应用数学的神奇的课上,老师教给大家如何处理小数的进制转换:

p进制的小数abc.def的十进制值为: a*p2+b*p+c+d/p+e/p2 +f/p^3 。

例如十进制数 1/3 在十进制下小数表示为0.33333…,在三进制下为0.1,在三十进制下为0.A。(这里A的含义与十六进制中A的含义相同,均表示10)。
下课后,老师要求kAc将N个十进制的分数写成k进制下的小数。然而kAc发现,很多十进制分数根本不可能写成有限的k进制小数!这令他十分不爽,不过他想知道,最小需要几进制才能使得这些十进制分数在该进制下均为有限的小数。

Input

第一行一个整数N
接下来N行,每行两个整数a, b,表示一个十进制小数a/b 。

Output

一个整数,表示最小进制数。这里,请按照十六进制输出,所有字母全部大写。(例如,如果答案为十进制下26,则输出1A)。

Sample Input

3
3 99
1 99
1 11

Sample Output

21

Data Constraint

对于20%的测试数据:n=1
对于50%的测试数据:n<=10,a, b <= 10000,保证最终答案在十进制下不超过10000。
对于70%的测试数据:n<=100,a, b<= 10000。
对于100%的测试数据:n<=1000,1 <= a,b <= 1000000000。

Hint

样例解释:
在33进制下,3/99可以表示为0.1,1/99可以表示为0.0B,1/11可以表示为0.3。
可以证明不存在更小的进制,使得他们均为有限小数。

题解

由于\(A\)最多只有一个大于\(\sqrt{A}\)的质因子,所以我们可以把小于\(\sqrt A\)的处理出来,再把剩下的取个重,然后乘起来就行了,注意使用高精度,时间复杂度\(\Theta(n\sqrt{b_{max}})\)。

code

#include<bits/stdc++.h>
#define rg register
#define fre(x)freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
using namespace std;
typedef long long LL;
typedef long double LD;
typedef double db;
typedef unsigned long long uLL;
const db Pi=acos(-1);
const int N=1e5;
int gcd(int a,int b){return (b==0)?a:gcd(b,a%b);}
int a[1005],b[1005],pr[100005],cnt;
bitset<100005> flag;
void init(){
	for(int i=2;i<=N;i++){
		if(!flag[i])pr[++cnt]=i;
		for(int j=i+i;j<=N;j+=i)
		flag[j]=1;
	}
	flag=0;
}
LL ans[100005];
int len=1;
void Times(int w){len+=15;
	for(int i=1;i<=len;i++)ans[i]*=w;
	for(int i=1;i<=len;i++)
	ans[i+1]+=ans[i]/16,ans[i]%=16;
	while(ans[len]==0)len--;
}
int main(){
	init();
	int n;scanf("%d",&n);
	for(int i=1,g;i<=n;i++){
		scanf("%d%d",&a[i],&b[i]);
		g=gcd(a[i],b[i]);
		a[i]/=g,b[i]/=g;
		for(int j=1;j<=cnt&&b[i]>1;j++)
		while(b[i]%pr[j]==0)
		b[i]/=pr[j],flag[j]=1;
	}
	ans[1]=1;
	sort(b+1,b+n+1);
	n=unique(b+1,b+n+1)-b-1;
	for(int i=1;i<=cnt;i++){
		if(!flag[i])continue;
		Times(pr[i]);
	}
	for(int i=1;i<=n;i++)Times(b[i]);
	for(int i=len;i;i--){
		if(ans[i]<10)printf("%d",ans[i]);
		else printf("%c",ans[i]-10+'A');
	}
    return 0;
}

T4有间医院

题面

Description

  从前有家医院,医院里有n个医生,分到4个组。每天进行医护工作时,每个组的医生都会有变动。每个医生都有一个特定的编号,而且都能分去4个组中的任意一个。
 在第一天,当医院开门时,医生会被按顺序分到四个组里面。如果这四个组的医生数目分别为g1, g2, g3, g4,那么分组方案会如下所示:
 第1组: 1, 2, …, g1
 第2组: g1+1, g1+2, …, g1+g2
 第3组: g1+g2+1, g1+g2+2, …, g1+g2+g3
 第4(0) 组: g1+g2+g3+1, g2+g2+g3+2, …, g1+g2+g3+g4
 然后,第一个病人会选择医生1,就诊结束后,医生1会被分到第2组的最后一个位置。第二个病人会选择医生g1+1,就诊结束后,医生g1+1会被分到第3组的最后一个位置……依次类似,第k个病人会选择第k%4组的第1个医生,就诊结束后,这个医生会被分到第(k+1)%4组的最后一个位置上。
 这间医院一天要处理m个病人。而且,在第二天开始前,这些医生会根据上一天最后的情况再进行编排。他们会把四个组首尾相接合并在一起,然后再重新按g1, g2, g3, g4来分组安排。
 例如,如果某天结束后的分组情况如下所示:
 第1组:d1,d2,....,d(k1) 第2组:d(k1+1),d(k1+2),.....,d(k2)
 第3组:d(k2+1),d(k2+2),...,d(k3)第4组:d(k3+1),d(k3+2),...,d(k4)
 合并后,变成:d1,d2,....,d(k1),d(k1+1),d(k1+2),.....,d(k2),d(k2+1),d(k2+2),...,d(k3),d(k3+1),d(k3+2),...,d(k4)
 最后,重新按g1, g2, g3, g4分组变成:
 第1组:d1,d2,...,d(g1)
 第2组:d(g1),d(g1+1),...,d(g1+g2)
 第3组:d(g1+g2+1),d(g1+g2+2),...,d(g1+g2+g3)
 第4组:d(g1+g2+g3+1),d(g1+g2+g3+2),...,d(g1+g2+g3+g4)
 然后新的一天又开始了,和第一天一模一样地继续处理新的病人。
 过了一些天后,我们会发现一个有趣的理解:医生的分组安排居然和第1天一模一样!你能告诉我这是第几天吗?

Input

  输入包含多组数据。
 对于每组数据,仅一行,包含五个整数g1,g2,g3,g4,p(1<=g1,g2,g3,g4<=20,p<=10000),分别表示第1组,第2组,第3组,第4组的人数,以及每天的病人数。
 当这五个整数都是0时表示输入结束。

Output

  对每组数据输出一行,表示在这天的时候医生的分组安排会和第1天一样。答案保证不会超过32位整数范围。

Sample Input

2 1 1 1 6
0 0 0 0 0

Sample Output

3

Hint

【样例解释】
第一天开始前的分组: g1: 1 2 g2:3 g3:4 g4:5
第1个病人之后: g1:2 g2:3 1 g3:4 g4:5
第2个病人之后: g1:2 g2:1 g3:4 3 g4:5
第3个病人之后: g1:2 g2:1 g3:3 g4:5 4
第4个病人之后: g1:2 5 g2:1 g3:3 g4:4
第5个病人之后: g1:5 g2:1 2 g3:3 g4:4
第6个病人之后: g1:5 g2:2 g3:3 1 g4:4
第一天结束后,分组情况是: g1: 5 2 g2:3 g3:1 g4:4
第二天结束后,分组情况是: g1:4 2 g2:3 g3:5 g4:1
第三天结束后,分组情况是: g1:1 2 g2:3 g3:4 g4:5

【数据说明】
对于50%的数据,每个文件的数据组数不超过100。
对于100%的数据,每个文件的数据组数不超过10000。

题解

这题没什么好说的,只需要模拟一天,连边然后看环长求最小公倍数即可,复杂度\(\Theta(g1+g2+g3+g4+P)\)。

code

#include<bits/stdc++.h>
#define rg register
#define fre(x)freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
using namespace std;
typedef long long LL;
typedef long double LD;
typedef double db;
typedef unsigned long long uLL;
const db Pi=acos(-1);
struct Edge{int Nxt,To;}Ed[105];
int Head[105],Cnt;
void Add(int u,int v){
	Ed[++Cnt]=(Edge){Head[u],v};
	Head[u]=Cnt;
}
bool vis[105];
int len;
void Dfs(int u){
	vis[u]=1;len++;
	for(int i=Head[u];i;i=Ed[i].Nxt)
	if(!vis[Ed[i].To])Dfs(Ed[i].To);
}
deque<int> flag[5];
LL gcd(LL a,LL b){return (b==0)?a:gcd(b,a%b);}
int main(){
	int g1,g2,g3,g4,p;
	while(scanf("%d%d%d%d%d",&g1,&g2,&g3,&g4,&p)!=EOF){
		memset(vis,0,sizeof(vis));
		memset(Head,0,sizeof(Head));Cnt=0;
		if(!g1&&!g2&&!g3&&!g4&&!p)break;
		for(int i=1;i<=g1;i++)flag[1].push_back(i);
		for(int i=g1+1;i<=g1+g2;i++)flag[2].push_back(i);
		for(int i=g1+g2+1;i<=g1+g2+g3;i++)flag[3].push_back(i);
		for(int i=g1+g2+g3+1;i<=g1+g2+g3+g4;i++)flag[4].push_back(i);
		for(int i=1;i<=p;i++){
			int u=flag[(i-1)%4+1].front();
			flag[(i-1)%4+1].pop_front();
			flag[i%4+1].push_back(u);
		}
		
		if(flag[1].size()<g1){
			int u=flag[2].front();
			flag[2].pop_front();
			flag[1].push_back(u);
		}
		if(flag[2].size()<g2){
			int u=flag[3].front();
			flag[3].pop_front();
			flag[2].push_back(u);
		}
		if(flag[3].size()<g3){
			int u=flag[4].front();
			flag[4].pop_front();
			flag[3].push_back(u);
		}
		
		for(int i=0;i<g1;i++){
			int u=flag[1].front();
			Add(u,i+1),flag[1].pop_front();	
		}
		for(int i=g1;i<g1+g2;i++){
			int u=flag[2].front();
			Add(u,i+1),flag[2].pop_front();
		}
		for(int i=g1+g2;i<g1+g2+g3;i++){
			int u=flag[3].front();
			Add(u,i+1),flag[3].pop_front();
		}
		for(int i=g1+g2+g3;i<g1+g2+g3+g4;i++){
			int u=flag[4].front();
			Add(u,i+1),flag[4].pop_front();
		}
		
		int ans=1;
		for(int i=1;i<=g1+g2+g3+g4;i++)
		if(!vis[i]){
			len=0;Dfs(i);
			ans=1ll*ans*len/gcd(ans,len); 
		}
		printf("%d\n",ans);
	}
    return 0;
}

标签:g4,g3,g2,g1,int,long,2022.10,模拟
From: https://www.cnblogs.com/dzrblog/p/16755578.html

相关文章

  • 2022.10.5java特性和优势
    Java构建工具:Ant,Maven,Jekins应用服务器:Tomcat,Jettty,Jboss,Websphere,weblogicWeb开发:Struts,Spring,Hibernate,myBatis开发工具:Eclipse,Netbean,intellij......
  • 原始递归函数及模拟运行的优化
    看到网上一个题目,证明x开y次方是原始递归函数(primitiverecursivefunction)。这个问题并不难,只要把x开y次方实现出来即可。于是,正好把《递归论》相关内容补一补。【......
  • CSP-S模拟14
    T1.考场:这不就单峰函数吗?我会3min后:这函数有相等区间啊!爬山3h后:woc这题写了3小时!赶紧去冲后几题暴力不过最后还是A了%:pragmaGCCoptimize(3)#include<bits/std......
  • 【闲话】2022.10.04闲话
    早起上luogu知道的第一件事竟然是没灯了。我大悲。等灯东,噔噔咚。然后今天开始切模拟&搜索真TM难切比莫反还TM离谱(不过似乎正是这样我才需要练这方面罢)字......
  • P3528 PAT-Sticks(2022.10.2)
    题目描述:戳这里题目大意:①给你k种颜色木棍,每种木棍个数不一样。②找出三根颜色不一样的木棍组成三角形。③如果可以输出方案,不能输出"NIE"。思路:遇事不决先看数据范......
  • [挑战记录]模拟/搜索题单
    2022100320:18[省选联考2022]预处理器\(\operatorname{string}\)科技题#include<cstdio>#include<cstring>#include<string>#include<iostream>#include<map>#de......
  • 2022.10.4
    考试,大概7、8名,基本是按流程来的了。还是有些问题,感觉很多题莫名奇妙没转过弯,拿了很高的部分分但距离正解还有距离。CF做少了QaQTodo:考试,改题(至少前三道)。把CF的E题和......
  • Cisco模拟器使用教程
    一、使用三层交换机实现跨VLAN间的通信1.vlan配置如图所示局域网,要将不同的PC机配置到不同的vlan下。在二层交换机的配置模式(即Switch(config)#)下:这里配置的端口是与P......
  • 43rd 2022/10/4 模拟赛总结30
    这次还行?rank5,其实也不是多高不可攀,就是认真打,暑假时就上过前五好多次其实比赛历程也很简单第一题很忽悠,思路乱的一批,但是这次冷静下来把思路理清就切了很简单的概率D......
  • 2022.10.04考试总结
    2022.10.04考试总结得分:\(110/300\)总结:今天的第一题比较简单,第二题因为看错题意并且思考了比较长的时间导致爆零,第三题在考场上没有一个比较完整并且容易实现的思路题......