20200728模拟
题目 |
覆盖 |
分组 |
部落 |
命名 |
cover.cpp |
grouping.cpp |
tribal.cpp |
内存 |
128M |
128M |
128M |
时限 |
1s |
1s |
1s |
1、覆盖(cover.cpp)(源自洛谷P1990 覆盖墙壁)
题目描述
你有一个长为N宽为2的墙壁,给你两种砖头:一个长2宽1,另一个是L型覆盖3个单元的砖头。如下图:
00
000
砖头可以旋转,两种砖头可以无限制提供。你的任务是计算用这两种来覆盖N*2的墙壁的覆盖方法。例如一个2*3的墙可以有5种覆盖方法,如下:
012 002011
001
011
012 112022
011
001
注意可以使用两种砖头混合起来覆盖,如2*4的墙可以这样覆盖:
0112
0012
给定N,要求计算2*N的墙壁的覆盖方法。由于结果很大,所以只要求输出最后4位。例如2*13的覆盖方法为13465,只需输出3465即可。如果答案少于4位,就直接输出就可以,不用加0,如N=3,时输出5。
输入格式
一个整数N(1<=N<=1000000),表示墙壁的长。
输出格式
输出覆盖方法的最后4位,如果不足4位就输出整个答案。
输入输出样例
输入
13
输出
3465
O(≧口≦)O推了半天没搞出递推式 0分
#include<bits/stdc++.h> #define R register int #define ll long long using namespace std; const int N=1e6+5,mod=10000; int n,f[N]; int read() { int f=1;char ch; while((ch=getchar())<'0'||ch>'9')if(ch=='-')f=-1; int res=ch-'0'; while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-'0'; return res*f; } void write(int x) { if(x<0) { putchar('-'); x=-x; } if(x>9)write(x/10); putchar(x%10+'0'); } int main() { //freopen("cover.in","r",stdin); //freopen("cover.out","w",stdout); n=read(); //f[0]=1; f[1]=1;f[2]=2;f[3]=5; if(n==1)putchar('1'); else if(n==2)putchar('2'); else if(n==3)putchar('5'); else { for(R i=4;i<=n;i++)f[i]=(2*f[i-1]+f[i-3])%mod; write(f[n]); } return 0; }
2、分组(grouping.cpp)(源自洛谷P4447 [AHOI2018初中组]分组)
题目描述
小可可的学校信息组总共有n 个队员,每个人都有一个实力值a[i]。现在,一年一度的编程大赛就要到了,小可可的学校获得了若干个参赛名额,教练决定把学校信息组的n个队员分成若干个小组去参加这场比赛。
但是每个队员都不会愿意与实力跟自己过于悬殊的队员组队,于是要求分成的每个小组的队员实力值连续,同时,一个队不需要两个实力相同的选手。举个例子:[1, 2, 3, 4, 5]是合法的分组方案,因为实力值连续;[1, 2, 3, 5]不是合法的分组方案,因为实力值不连续;[0, 1, 1, 2]同样不是合法的分组方案,因为出现了两个实力值为1 的选手。
如果有小组内人数太少,就会因为时间不够而无法获得高分,于是小可可想让你给出一个合法的分组方案,满足所有人都恰好分到一个小组,使得人数最少的组人数最多,输出人数最少的组人数的最大值。
注意:实力值可能是负数,分组的数量没有限制。
输入格式
输入有两行:
第一行一个正整数n,表示队员数量。
第二行有n 个整数,第i 个整数a[i]表示第i 个队员的实力。
输出格式
输出一行,包括一个正整数,表示人数最少的组的人数最大值。
输入输出样例
输入
7
4 5 2 3 -4 -3 -5
输出
3
说明/提示
【样例解释】 分为2 组,一组的队员实力值是{4, 5, 2, 3}一组是{-4, -3, -5}其中最小的组人数为3,可以发现没有比3 更优的分法了。
【数据范围】
对于100%的数据满足:1≤n≤100000,|a[i]|≤10^9。
本题共10 个测试点,编号为1~10,每个测试点额外保证如下:
1~2 n≤6, 1≤a[i]≤100
3~4 n≤1000, 1≤a[i]≤10^5且a[i]互不相同
5~6 n≤100000, a[i]互不相同
7~8 n≤100000, 1≤a[i]≤10^5
9~10 n≤100000, |a[i]|≤10^9
#include<bits/stdc++.h> #define R register int #define ll long long using namespace std; const int N=1e6+5,inf=0x3f3f3f3f; int n,a[N]; int read() { int f=1;char ch; while((ch=getchar())<'0'||ch>'9')if(ch=='-')f=-1; int res=ch-'0'; while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-'0'; return res*f; } void write(int x) { if(x<0) { putchar('-'); x=-x; } if(x>9)write(x/10); putchar(x%10+'0'); } int main() { //freopen("grouping.in","r",stdin); //freopen("grouping.out","w",stdout); n=read(); for(R i=1;i<=n;i++)a[i]=read(); sort(a+1,a+1+n); int num=1,ans=inf; for(R i=2;i<=n;i++) { if(a[i-1]+1==a[i])num++; else if(a[i-1]+1!=a[i]) { ans=min(ans,num); num=1; } } write(ans); return 0; }
#include<bits/stdc++.h> #define R register int #define ll long long using namespace std; const int N=1e6+5,inf=0x3f3f3f3f; int n,a[N]; int read() { int f=1;char ch; while((ch=getchar())<'0'||ch>'9')if(ch=='-')f=-1; int res=ch-'0'; while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-'0'; return res*f; } void write(int x) { if(x<0) { putchar('-'); x=-x; } if(x>9)write(x/10); putchar(x%10+'0'); } int main() { //freopen("grouping.in","r",stdin); //freopen("grouping.out","w",stdout); n=read(); for(R i=1;i<=n;i++)a[i]=read(); sort(a+1,a+1+n); int num=1,ans=inf; for(R i=2;i<=n+1;i++) { if(a[i-1]+1==a[i])num++; else { ans=min(ans,num); num=1; } } write(ans); return 0; }
#include<bits/stdc++.h> #define R register int #define ll long long using namespace std; const int N=1e6+5,inf=0x3f3f3f3f; int n,a[N]; int read() { int f=1;char ch; while((ch=getchar())<'0'||ch>'9')if(ch=='-')f=-1; int res=ch-'0'; while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-'0'; return res*f; } void write(int x) { if(x<0) { putchar('-'); x=-x; } if(x>9)write(x/10); putchar(x%10+'0'); } struct node{ int la,num; }b[N]; int main() { //freopen("grouping.in","r",stdin); //freopen("grouping.out","w",stdout); n=read(); for(R i=1;i<=n;i++)a[i]=read(); sort(a+1,a+1+n); int cnt=0; for(R i=1;i<=n;i++) { bool flag=false; for(R j=cnt;j;j--) { if(b[j].la+1==a[i]) { flag=true; b[j].num++; b[j].la++; break; } } if(!flag) { b[++cnt].num=1; b[cnt].la=a[i]; } } int ans=inf; for(R i=1;i<=cnt;i++)ans=min(ans,b[i].num); write(ans); return 0; }
3、部落(tribal.cpp)(源自洛谷P4047 [JSOI2010]部落划分)
题目描述
聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是拉帮结派形成属于自己的部落,不同的部落之间则经常发生争斗。只是,这一切都成为谜团了——聪聪根本就不知道部落究竟是如何分布的。
不过好消息是,聪聪得到了一份荒岛的地图。地图上标注了 n个野人居住的地点(可以看作是平面上的坐标)。我们知道,同一个部落的野人总是生活在附近。我们把两个部落的距离,定义为部落中距离最近的那两个居住点的距离。聪聪还获得了一个有意义的信息——这些野人总共被分为了 k 个部落!这真是个好消息。聪聪希望从这些信息里挖掘出所有部落的详细信息。他正在尝试这样一种算法:
对于任意一种部落划分的方法,都能够求出两个部落之间的距离,聪聪希望求出一种部落划分的方法,使靠得最近的两个部落尽可能远离。
例如,下面的左图表示了一个好的划分,而右图则不是。请你编程帮助聪聪解决这个难题。
输入格式
输入文件第一行包含两个整数 n和 k,分别代表了野人居住点的数量和部落的数量。
接下来 n行,每行包含两个整数 x,y,描述了一个居住点的坐标。
输出格式
输出一行一个实数,为最优划分时,最近的两个部落的距离,精确到小数点后两位。
输入输出样例
输入 #1
4 2
0 0
0 1
1 1
1 0
输出 #1
1.00
输入 #2
9 3
2 2
2 3
3 2
3 3
3 5
3 6
4 6
6 2
6 3
输出 #2
2.00
说明/提示
数据规模与约定
对于 100% 的数据,保证 2≤k≤n≤10^3, 0≤x,y≤10^4。
#include<bits/stdc++.h> #define R register int #define ll long long using namespace std; const int N=1e6+5; int n,k,t,fa[1005]; struct node{ int x,y; }a[1005]; struct Node{ int x,y; double dis; /*bool operator <(const Node &p)const { return dis<p.dis; }*/ }b[N]; int read() { int f=1;char ch; while((ch=getchar())<'0'||ch>'9')if(ch=='-')f=-1; int res=ch-'0'; while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-'0'; return res*f; } void write(int x) { if(x<0) { putchar('-'); x=-x; } if(x>9)write(x/10); putchar(x%10+'0'); } int find(int x) { if(fa[x]!=x)return fa[x]=find(fa[x]); return x; } int main() { //freopen("tribal.in","r",stdin); //freopen("tribal.out","w",stdout); n=read();k=read(); for(R i=1;i<=n;i++) { a[i].x=read();a[i].y=read(); } //double ma=0; for(R i=1;i<=n;i++) { for(R j=1;j<i;j++) //if(i!=j) { b[++t].dis=sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y)); b[t].x=i;b[t].y=j; //if(b[t].dis>ma)ma=b[t].dis; //printf("g[%d][%d]=%lf\n",i,j,g[i][j]); } } //sort(b+1,b+1+t); double l=0,r=100000000;//r=ma; while(l+0.0001<r) { double mid=(l+r)/2; //cout<<mid<<endl; int num=0; for(R i=1;i<=n;i++)fa[i]=i; for(R i=1;i<=t;i++) { if(b[i].dis>mid)continue; int aa=b[i].x,bb=b[i].y; int faa=find(aa),fbb=find(bb); if(faa!=fbb)fa[fbb]=faa; //printf("find(%d)=%d,find(%d)=%d\n",aa,faa,bb,fbb); } for(R i=1;i<=n;i++) { if(fa[i]==i)num++; } //cout<<num<<endl; if(num>=k)l=mid; else r=mid; } printf("%.2lf",l); return 0; } /*if(judge(d[mid]))l=mid; else r=mid-1;*/