博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
集训队日常训练20181110 DIV2 题解及AC代码
阅读量:6097 次
发布时间:2019-06-20

本文共 13503 字,大约阅读时间需要 45 分钟。

4375: 孪生素数 分享至QQ空间

Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByte
Total Submit: 324            Accepted:91

Description

 

所谓孪生素数指的就是间隔为 2 的相邻素数,它们之间的距离已经近得不能再近了,就象孪生兄弟一样。最小的孪生素数是 (3, 5),在 100 以内的孪生素数还有 (5, 7), (11, 13), (17, 19), (29, 31), (41, 43), (59, 61) 和 (71, 73),总计有 8 组。但是随着数字的增大,孪生素数的分布变得越来越稀疏,寻找孪生素数也变得越来越困难。那么会不会在超过某个界限之后就再也不存在孪生素数了呢?

孪生素数有无穷多对!这个猜想被称为孪生素数猜想,至今没有被严格证明。但借助于计算机我们确实可以找到任意大数范围内的所有孪生素数对,接下来给定一个数k,求第k组孪生素数。

 

Input

 

输入数据有多组,每行为一个正整数k(1<= k <=10000)。

 

Output

 

输出有两个整数,以空格隔开,表示第k组孪生素数。

 

Sample Input

 1

Sample Output

 3 5

素数序列Pn,其中Pi+1-Pi=2为孪生素数(素数永远是人们着迷的话题,包括今年非常火的黎曼猜想)

我们可以知道,这个数并不多,但是让求的也不多,暴力走一波

1可以先预处理出这些数,判断x和x+2都是素数

Solution from 

#include
#include
#include
using namespace std;bool x(int m){ int i; int t=sqrt(m); for(i=2;i<=t;i++) { if(m%i==0) return false; } return true;}int main(){ int a[15000]; int i,j,n,k=0; for(i=3;i<1400000;i++) { if(x(i)&&x(i+2)) a[k++]=i; } while(scanf("%d",&n)!=EOF) { printf("%d %d\n",a[n-1],a[n-1]+2); }}

 2预处理素数表然后去保存答案的,这个当然要快一些

Solution from  

#include
#include
#include
#include
#include
using namespace std;bool a[1300010];int b[500000];int h;struct didi{ int x,y;} c[10010];void pf(){ a[0]=a[1]=true; for(int i=2; i<=sqrt(1300000); i++) { if(!a[i]) { for(int j=i+i; j<=1300000; j+=i) a[j]=true; } } h=0; for(int i=0; i<1300000; i++) { if(!a[i]) b[h++]=i; } int num=1; for(int i=1; i

5471: 数据结构实验--图的最小代价生成树 分享至QQ空间

Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByte
Total Submit: 62            Accepted:14

Description

 

 

求带权无向图的最小代价生成树。

 

 

 

 

Input

 

 

输入数据为多组,每组数据包含多行,第一行为2个整数n,e,n为图的顶点数,e为边数,接下来是e行,每行3个整数,前两个整数是一个顶点对,代表一条边所依附的两个顶点,第3个整数是边的权值。

所有值不超过20。

 

 

Output

 

 

请使用prim算法生成一棵生成树,并输出为生成树的各条边及其权值。格式见样例。

 

 

 

Sample Input

 

5 7

1 2 1
1 3 1
2 3 4
2 4 2
2 5 1
3 4 5
4 5 6

Sample Output

 

1 2 1

1 3 1
2 5 1
2 4 2

B题就是Prim算法,但是呢,需要去理解这个模板吧(Prim加点,Kruskal加边)

Solution from 

#include
using namespace std;const int N=105;const int INF=0x3f3f3f3f;int lowc[N],vis[N],G[N][N],fa[N];int Prim(int n){ vis[1]=1; for(int i=2;i<=n;i++)lowc[i]=G[1][i],fa[i]=1; for(int i=2;i<=n;i++) { int minc=INF; int p=-1; for(int j=1;j<=n;j++) if(!vis[j]&&minc>lowc[j]) minc=lowc[j],p=j; printf("%d %d %d\n",fa[p],p,minc); vis[p]=1; for(int j=1;j<=n;j++) if(!vis[j]&&lowc[j]>G[p][j]) lowc[j]=G[p][j],fa[j]=p; }}int main(){ int n,e,u,v,w; while(scanf("%d%d",&n,&e)!=EOF) { memset(G,INF,sizeof(G)); memset(vis,0,sizeof(vis)); for(int i=0;i

5488: 石子归并II 

N堆石子摆成一个环。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价。计算将N堆石子合并成一堆的最小代价。

 

例如: 1 2 3 4,有不少合并方法

1 2 3 4 => 3 3 4(3) => 6 4(9) => 10(19)

1 2 3 4 => 1 5 4(5) => 1 9(14) => 10(24)

1 2 3 4 => 1 2 7(7) => 3 7(10) => 10(20)

 

括号里面为总代价可以看出,第一种方法的代价最低,现在给出n堆石子的数量,计算最小合并代价。

 

 

Input

 

第1行:N(2 <= N <= 1000)

第2 - N + 1:N堆石子的数量(1 <= A[i] <= 10000)

 

Output

 

输出最小合并代价。

 

Sample Input

 

4

1
2
3
4

Sample Output

 19

区间DP+四边形优化

属于拉题人强行引导题,比较困难,有时间的可以去学学

solution from 

#include 
using namespace std;const int INF=0x3f3f3f3f;int dp[2005][2005];int a[2005][2005],pre[2005][2005],s[2005][2005];int main(){ int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i][i]),a[i+n][i+n]=a[i][i]; for(int i=1;i<=n<<1;i++) for(int j=i;j<=n<<1;j++) pre[i][j]=pre[i][j-1]+a[j][j]; memset(dp,INF,sizeof dp); for(int i=1;i<=n<<1;i++) s[i][i]=i,dp[i][i]=0; for(int l=1;l
dp[i][k]+dp[k+1][j]+pre[i][j]) dp[i][j]=dp[i][k]+dp[k+1][j]+pre[i][j],s[i][j]=k; } int minn=INF; for(int i=1;i<=n;i++) minn=min(minn,dp[i][i+n-1]); printf("%d\n",minn); return 0;}

4025: 游西湖 分享至QQ空间

Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByte
Total Submit: 149            Accepted:62

Description

 

游山玩水是zzd的爱好之一,一天,zzd和朋友一共N个人在西湖游玩游玩,看到西湖这么宽,大家都想划船到对岸去,但是一艘船只能容纳两个人,当然也可以一个人划的,像zzd这样的胖子一个人划空间比较宽敞,其中一人到了对岸还必须把船划回来,不然后面的人就要着急了,一个人过河的时间是自己花费的时间,,两个人同时过桥的时候,花费的时间为两个人中速度最慢的那个人花费的时间,如何设计一个方案,zzd和他的朋友尽快过桥?

                                        

 

Input

 

输入数据有多组

每组测试数据的第一行是一个整数N(1<=N<=1000)表示共有N个人要过河
每组测试数据的第二行是N个整数Si,表示此人过河所需要花时间。(0<Si<=100)

程序以N=0结束

 

Output

 

输出所有人过河的最短时间

 

Sample Input

4

1 2 5 10
0

Sample Output

 17

样例解释:1、2过去,1回来,5、10过去,2回来,1、2过去

 通过两个小的将两个大的运过去。
每次都是最小和次小过去,然后最小回来,然后两个大的过去,次小回来,这样两个大的就过去了,以此类推。
偶数个的话,最后留两个,奇数个的话,最后留三个,手动模拟一下即可。 

solution from 

#include 
using namespace std;int a[1005];int main(){ int n; while(~scanf("%d",&n),n) { for(int i=0;i

 

3659: 神奇的探险之旅 分享至QQ空间

Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByte
Total Submit: 106            Accepted:17

Description

 

我们正在设计这样的一款儿童探险游戏:游戏由很多故事场景组成,每个场景中都有一个问题,游戏根据玩家的回答将进入下一场景,经过巧妙的设计,我们保证在一次“探险旅行”中,不会重复的进入任何相同的场景,因此最终探险故事将根据玩家的选择结束在某个场景中。玩家总希望能够让自己的探险之旅尽可能的长,给定故事情节布局,请判断最长能够到达多少个场景?

我们对故事的m个场景进行编号(1~m),并且每次都是从编号为1开始探险之旅。

 

Input

 

输入数据有多组,每组数据的第一行位一个正整数n,表示数据的组数。

每组数据的第一行为一个正整数m(1<m<1000),表示故事场景的总数,接下来有m行,第i行描述了第i个场景的信息,包括3种情况:
(1)如果该行包含1个正整数j,则表示由第i个故事场景只能到达第j个场景;
(2)如果该行包含2个正整数j和k,则表示由第i个故事场景可以到达第j或者k个场景;
(3)如果该行包含1个字符串“ENDING”,表示故事在第i个场景结束;

 

Output

 

每组数据输出格式如下:

Case #x: y

x为测试数据编号,从1开始计算,y为一个整数,表示最多能经过的场景数量。

 

Sample Input

 

2

3
2 3
ENDING
ENDING
5
4 5
ENDING
2
3
4

Sample Output

Case #1: 2

Case #2: 5

转化为最短路,负权值跑最短路就是正权值跑最长路

Solution from 

#include
using namespace std;const int maxn=1005;int T,sum,n,o=1,d[maxn];vector< vector
>G(maxn);int dij(){ memset(d,0,sizeof d); queue
q; q.push(1); while(!q.empty()) { int u=q.front();q.pop(); for(auto v:G[u]) { if(d[v]>d[u]-1) { d[v]=d[u]-1; q.push(v); } } } return *min_element(d+1,d+1+n)*-1;}int main(){ string s; cin>>T; while(T--) { cin>>n; cin.get(); for(int i=1;i<=n;i++) { G[i].clear(); getline(cin,s); if(s[0]=='E')continue; stringstream ss(s); while(ss>>sum)G[i].push_back(sum); } printf("Case #%d: %d\n",o++,dij()+1); } return 0;}

5271: 质因数的个数 分享至QQ空间

Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByte
Total Submit: 945            Accepted:319

Description

 

求正整数N(N>1)的质因数的个数。

相同的质因数需要重复计算。如120=2*2*2*3*5,共有5个质因数。

 

 

Input

 

可能有多组测试数据,每组测试数据的输入是一个正整数N,(1<N<10^9)。

 

Output

 

对于每组数据,输出N的质因数的个数。

 

Sample Input

 

Sample Output

 

Hint

注意:1不是N的质因数;若N为质数,N是N的质因数。

属于这次的友情送温暖题目
相信大家一定也会求其因子数,也是乘法原理x=a1^b1*a2^b2*…(b1 b2…是质数) 因子数为(b1+1)*(b2+1)*….
Solution from 
#include 
#include
int main(){ int t,i,j,n; while(~scanf("%d",&n)) { t=0; for(j=2; j<=sqrt(n); j++) { if(n%j==0) { while(n%j==0) { n/=j; t++; } } } if(n>1) t++; printf("%d\n",t); }}

4859: 分数线划定 分享至QQ空间

Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByte
Total Submit: 104            Accepted:60

Description

 

 

世博会志愿者的选拔工作正在 A 市如火如荼的进行。为了选拔最合适的人才,A 市对所有报名的选手进行了笔试,笔试分数达到面试分数线的选手方可进入面试。面试分数线根据计划录取人数的150%划定,即如果计划录取m名志愿者,则面试分数线为排名第m*150%(向下取整)名的选手的分数,而最终进入面试的选手为笔试成绩不低于面试分数线的所有选手。

现在就请你编写程序划定面试分数线,并输出所有进入面试的选手的报名号和笔试成绩。

【样例说明】

m*150% = 3*150% = 4.5,向下取整后为4。保证4 个人进入面试的分数线为88,但因为88有重分,所以所有成绩大于等于88 的选手都可以进入面试,故最终有5 个人进入面试。

 

 

 

Input

 

 

第一行,两个整数n,m(5 ≤ n ≤ 5000,3 ≤ m ≤ n),中间用一个空格隔开,其中n 表示报名参加笔试的选手总数,m 表示计划录取的志愿者人数。输入数据保证m*150%向下取整后小于等于n。

第二行到第 n+1 行,每行包括两个整数,中间用一个空格隔开,分别是选手的报名号k(1000 ≤ k ≤ 9999)和该选手的笔试成绩s(1 ≤ s ≤ 100)。数据保证选手的报名号各不相同。

 

 

Output

 

 

第一行,有两个整数,用一个空格隔开,第一个整数表示面试分数线;第二个整数为进入面试的选手的实际人数。

从第二行开始,每行包含两个整数,中间用一个空格隔开,分别表示进入面试的选手的报名号和笔试成绩,按照笔试成绩从高到低输出,如果成绩相同,则按报名号由小到大的顺序输出。

 

 

 

Sample Input

 

6 3

1000 90
3239 88
2390 95
7231 84
1005 95
1001 88

Sample Output

 

88 5

1005 95
2390 95
1000 90
1001 88
3239 88

sort就完事

Solution from  

#include
#include
#include
using namespace std;struct node{ int x,y;} a[10000];bool cmp(node s,node d){ if(s.y==d.y) return s.x
d.y;}int main(){ int n,i,j,t,k; scanf("%d%d",&n,&k); k=k*1.5; for(i=0; i

4822: 计算系数 分享至QQ空间

Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByte
Total Submit: 42            Accepted:14

Description

 

给定一个多项式(ax + by)k,请求出多项式展开后xnym项的系数。

【数据范围】

对于 30%的数据,有0≤k≤10;

对于 50%的数据,有a = 1,b = 1;

对于 100%的数据,有0≤k≤1,000,0≤n, m≤k,且n + m = k,0≤a,b≤1,000,000。

 

Input

 

共一行,包含 5 个整数,分别为a,b,k,n,m,每两个整数之间用一个空格隔开。

 

 

Output

 

输出共 1 行,包含一个整数,表示所求的系数,这个系数可能很大,输出对10007 取模后的结果。

 

Sample Input

 1 1 3 1 2

Sample Output

 3

可以组合数,可以DP

Solution from  (我滚动了一下,卡下空间,学滚动可以到)

#include 
#define K 10007int f[2][1005];int main(){ int a,b,n,m,k,i,j; scanf("%d%d%d%d%d",&a,&b,&k,&n,&m); b%=K,a%=K; int op=1; f[1][0]=b,f[1][1]=a; for(i=2; i<=k; i++) { op^=1; for(j=0; j<=i&&j<=n; j++) { f[op][j]=f[op^1][j]*b%K; if(j) f[op][j]=(f[op][j]+f[op^1][j-1]*a)%K; } } printf("%d\n",f[op][n]); return 0;}

Solution from  

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;#define LL long long#define pb push_back#define mk make_pair#define pill pair
#define mst(a, b) memset(a, b, sizeof a)#define REP(i, x, n) for(int i = x; i <= n; ++i)#define pi acos(-1.0)#define Max_N 1001#define INF 2000000000#define f(i,a,b) for(i = a;i<=b;i++)#define fi(i,a,b) for(i = a;i>=b;i--)#define LL long longusing namespace std;#include
const int N = 200000 + 5;const LL MOD = 10007LL;LL F[N], Finv[N], inv[N];//F是阶乘,Finv是逆元的阶乘void init(){ inv[1] = 1; for(int i = 2; i < N; i ++) { inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD; } F[0] = Finv[0] = 1; for(int i = 1; i < N; i ++) { F[i] = F[i-1] * 1ll * i % MOD; Finv[i] = Finv[i-1] * 1ll * inv[i] % MOD; }}LL comb(int n, int m) //comb(n, m)就是C(n, m){ if(m < 0 || m > n) return 0; return F[n] * 1ll * Finv[n - m] % MOD * Finv[m] % MOD;}LL q(int a,int b){ LL ans = 1; LL di = a*1LL; while(b) { if(b&1) ans = (ans * di * 1LL)%MOD; di = di * di %MOD; b>>=1; } return ans%MOD;}int main(){ init(); int a,b,k,n,m; scanf("%d %d %d %d %d",&a,&b,&k,&n,&m); cout<<((comb(k,n)*q(a,n))%MOD*q(b,m))%MOD<

4507: 构造矩阵 分享至QQ空间

Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByte
Total Submit: 96            Accepted:60 Special Judge

Description

 

给定一个矩阵A,请构造一个对称矩阵B和反对称矩阵C,使得B+C=A。

如果满足MT=M,则称矩阵M为对称矩阵。

如果满足-MT=M,则称矩阵M为反对称矩阵。

MT称为M的转置矩阵。

 

Input

 

输入数据的第一行为一个正整数N(N<10),表示矩阵A的行数(或列数)。

接下来有N行,每行N个整数,表示矩阵的元素。

 

Output

 

先输出矩阵B,共有N数,每行有N个整数。

接下来输出一个空行。
再输出矩阵B,共有N行,每行有N个整数。

如果有多个结果,只要输出其中一个。

数据保证至少有一个解。

 

Sample Input

 

2

2 2
4 4

Sample Output

 

2 3

3 4

0 -1

1 0

比较神奇的构造

Solution from  

#include
#include
using namespace std;int main(){ int n,j,a[10][10],i; cin>>n; for(i=0; i
>a[i][j]; } } for(i=0; i

3039: 材质贴图 分享至QQ空间

Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByte
Total Submit: 50            Accepted:21

Description

3D游戏中的场景经常用材质贴图来表现,例如石头、水面等。

通常,材质贴图是一张正方形的位图,上下边界的像素对应相同,左右边界的像素也对应相同。例如下图中,左边是一张材质贴图,而右边的不是(左右边界不同)。
给定一张n×n的位图,请在这张位图中寻找一块材质贴图,使得材质贴图尺寸最大。下图中黄色区域就是最大的材质贴图,虽然黄色区域左上角2×2的位图也是材质贴图,但不是最大的。

Input

输入包含多组数据。

每组数据第一行是一个整数n (1≤n≤50),表示位图的大小。
然后n行每行n个在0到255之间的整数,描述位图的内容。
输入数据以n=0结束,不要处理这组数据。

Output

对每组数据输出最大的材质贴图的边长。请注意,1×1的位图也是材质贴图。

Sample Input

 

2

255 0
0 127
5
5 251 127 11 195
23 13 0 13 23
211 0 13 0 67
211 13 0 13 23
1 251 127 11 47
0

Sample Output

 

1

3

往中间走,然后暴力枚举

Solution from 

#include
int n,a[51][51];int la(){ for(int k=n; k>2; k--) for(int i=0; i<=n-k; i++) for(int j=0; j<=n-k; j++) { int f=1; for(int l=0; l

Solution from 

#include
using namespace std;int main(){ int t,a[51][51],x,y; while(cin>>t,t) { int sme=1; for(int i=0; i
>a[i][j]; } } for(int i=0; i
sme) sme=(x-i)+1; } x++; y++; } } } cout<
<

 

转载于:https://www.cnblogs.com/BobHuang/p/9939855.html

你可能感兴趣的文章
智力大冲浪
查看>>
JSONP实现跨域
查看>>
Python基础班---第一部分(基础)---Python基础知识---计算机组成原理
查看>>
虚拟机VMware 9安装苹果MAC OSX 10.8图文教程
查看>>
POJ3694 Network
查看>>
微信小程序开发-框架
查看>>
redo、undo、binlog的区别
查看>>
DropDownList 控制日期控件显示格式
查看>>
RecycleView设置顶部分割线(记录一个坑)
查看>>
【设计模式系列】单例模式的7种写法
查看>>
汉字转拼音 (转)
查看>>
Machine Learning Techniques -6-Support Vector Regression
查看>>
会计基础_001
查看>>
Cordova 开发环境搭建及创建第一个app
查看>>
ajax请求拿到多条数据拼接显示在页面中
查看>>
小程序: 查看正在写的页面
查看>>
dedecms生成文档数据库崩溃 mysql daemon failed to start
查看>>
Linux的50个基本命令
查看>>
Objective-C中创建单例方法的步骤
查看>>
[转]无法安装MVC3,一直卡在vs10-kb2483190
查看>>