noip2015 提高组day1、day2

NOIP201505神奇的幻方
 
试题描述

    幻方是一种很神奇的N∗N矩阵:它由数字 1,2,3,……,N∗N构成,且每行、每列
及两条对角线上的数字之和都相同。
    当N为奇数时,我们可以通过以下方法构建一个幻方:
    首先将 1 写在第一行的中间。
    之后,按如下方式从小到大依次填写每个数 K(K= 2,3,…,N∗N) :
    1. 若 (K − 1) 在第一行但不在最后一列,则将K 填在最后一行,(K − 1) 所在列
       的右一列;
    2. 若 (K − 1) 在最后一列但不在第一行,则将K 填在第一列,(K − 1) 所在行的上
       一行;
    3. 在第一行最后一列,则将K 填在(K − 1) 的正下方;
    4. 若 (K − 1) 既不在第一行,也不在最后一列,如果 (K − 1) 的右上方还未填数,
       则将 K 填在(K − 1)的右上方,否则将K 填在 (K − 1) 的正下方。

        现给定 N,请按上述方法构造 N ∗ N 的幻方。

输入
输入文件名为 magic.in 。
输入文件只有一行,包含一个整数 N,即幻方的大小。
输出
输出文件名为 magic.out 。
输出文件包含N 行,每行N 个整数,即按上述方法构造出的 N ∗ N 的幻方。
相邻两个整数之间用单个空格隔
输入示例
magic.in 
3
输出示例
magic.out
8 1 6
3 5 7
4 9 2
其他说明
对于 100% 的数据,1 ≤ N ≤ 39 且 N 为奇数。
 1 #include<iostream>
 2 using namespace std;
 3 int n;
 4 int a[41][41];
 5 int k1[2000],k2[2000];
 6 int main()
 7 {
 8     scanf("%d",&n);
 9     a[1][n/2+1]=1;
10     k1[1]=1;k2[1]=n/2+1;
11     for(int i=2;i<=n*n;i++)
12     {
13         if(k1[i-1]==1&&k2[i-1]!=n)
14         {
15             a[n][k2[i-1]+1]=i;
16             k1[i]=n;k2[i]=k2[i-1]+1;
17         }
18         else if(k2[i-1]==n&&k1[i-1]!=1)
19         {
20             a[k1[i-1]-1][1]=i;
21             k1[i]=k1[i-1]-1;k2[i]=1;
22         }
23         else if(k1[i-1]==1&&k2[i-1]==n)
24         {
25             a[2][n]=i;
26             k1[i]=2;k2[i]=n;
27         }
28         else
29         {
30             if(!a[k1[i-1]-1][k2[i-1]+1])
31             {
32                 a[k1[i-1]-1][k2[i-1]+1]=i;
33                 k1[i]=k1[i-1]-1;k2[i]=k2[i-1]+1;
34             }
35             else
36             {
37                 a[k1[i-1]+1][k2[i-1]]=i;
38                 k1[i]=k1[i-1]+1;k2[i]=k2[i-1];
39             }
40         }
41     }
42     for(int i=1;i<=n;i++)
43     {
44         printf("%d",a[i][1]);
45         for(int j=2;j<=n;j++) printf(" %d",a[i][j]);
46         printf("
");
47     }
48 }
View Code
NOIP201506信息传递
 
试题描述

 有N 个同学(编号为 1 到 N)正在玩一个信息传递的游戏。在游戏里每人都有一个
固定的信息传递对象,其中,编号为 i 的同学的信息传递对象是编号为 Ti 的同学。
游戏开始时,每人都只知道自己的生日。之后每一轮中,所有人会同时将自己当前
所知的生日信息告诉各自的信息传递对象

(注意: 可能有人可以从若干人那里获取信息,但是每人只会把信息告诉一个人,即自己的信息传递对象) 。当有人从别人口中得知自己的生日时,游戏结束。请问该游戏一共可以进行几轮?

输入
共 2 行。第 1 行包含 1 个正整数 N,表示 N 个人。
第 2 行包含 N 个用空格隔开的正整数 T1 ,T2 ,……,Tn , 其中第 i 个整数Ti 表示编号为 i
的同学的信息传递对象是编号为 Ti 的同学,
Ti ≤ N 且 Ti ≠ i。
数据保证游戏一定会结束。
输出
共 1 行,包含 1 个整数,表示游戏一共可以进行多少轮 。
输入示例
5
2 4 2 3 1
输出示例
3
其他说明
数据范围:对于 100% 的数据,N ≤ 200000。
 1 #include<iostream>
 2 using namespace std;
 3 int read()
 4 {
 5     char x;
 6     int f=0;
 7     x=getchar();
 8     while(x<'0'&&x>'9') x=getchar();
 9     while(x>='0'&&x<='9')
10     {
11         f=f*10+x-'0';
12         x=getchar();
13     }
14     return f;
15 }
16 
17 int n,minn=2147483647,temp=0,s1=0,s2=0;
18 int a[200001],b[200001];
19 int dfs(int i)
20 {
21     if(b[i])
22     {
23         s1=i;
24         s2=1;
25         temp=0;
26         return 0;
27     }
28     b[i]=1;
29     int hh=dfs(a[i]);
30     if(s2) hh++;
31     if(i==s1) s2=0,temp=1;
32     return hh;
33 }
34 int main()
35 {
36     n=read();
37     for(int i=1;i<=n;i++) a[i]=read();
38     for(int i=1;i<=n;i++)
39     {
40         int ls;
41         if(!b[i]) ls=dfs(i);
42         if(ls<minn&&temp) minn=ls;
43     }
44     printf("%d",minn);
45 }
View Code
NOIP201508跳石头
 
试题描述

一年一度的“跳石头”比赛又要开始了!这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间,有 N 块岩石(不含起点和终点的岩石) 。在比赛过程中,选手们将从起点出发,每一步跳向相邻的岩石,直至到达终点。为了提高比赛难度,组委会计划移走一些岩石,使得选手们在比赛过程中的最短跳跃距离尽可能长。由于预算限制,组委会至多从起点和终点之间移走 M 块岩石(不能移走起点和终点的岩石) 。

输入
第一行包含三个整数 L,N,M,分别表示起点到终点的距离,起点和终点之间的岩石数,以及组委会至多移走的岩石数。接下来 N 行,每行一个整数,第 i 行的整数 Di( 0 < Di < L )表示第 i 块岩石与起点的距离。这些岩石按与起点距离从小到大的顺序给出,且不会有两个岩石出现在同一个位置。
输出
只包含一个整数,即最短跳跃距离的最大值。
输入示例
25 5 2
2
11
14
17
21
输出示例
4
其他说明
【样例说明】将与起点距离为 2 和 14 的两个岩石移走后,最短的跳跃距离为 4(从与起点距离17 的岩石跳到距离 21 的岩石,或者从距离 21 的岩石跳到终点) 。
【数据范围】100%的数据,0 ≤ M ≤ N ≤ 50,000,1 ≤ L ≤ 1,000,000,000。
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<string.h>
 4 #include<cstdio>
 5 #define re(i) i=read()
 6 #define rep(i,a,b) for(int i=a;i<=b;i++)
 7 using namespace std;
 8 int read()
 9 {
10     int f=0;
11     char x;
12     x=getchar();
13     while(x<'0'||x>'9') x=getchar();
14     while(x>='0'&&x<='9')
15     {
16         f=f*10+x-'0';
17         x=getchar();
18     }
19     return f;
20 }
21 int l,n,m;
22 int a[50010],b,c;
23 bool pd(int mid)
24 {
25     int last=0;
26     int ans=0;
27     rep(i,1,n)
28         if(a[i]-last<mid) ans++;
29         else last=a[i];
30     if(ans>m) return 0;
31     return 1;
32 }
33 int main()
34 {
35     re(l),re(n),re(m);
36     rep(i,1,n) re(a[i]);
37     a[n+1]=l;n++;
38     int L=0,R=l;
39     while(L<=R)
40     {
41         int mid=(L+R)/2;
42         if(pd(mid)) L=mid+1;
43         else R=mid-1;
44     }
45     printf("%d",L-1);
46 }
View Code
O(∩_∩)O~ (*^__^*) 嘻嘻…… O(∩_∩)O哈哈~
原文地址:https://www.cnblogs.com/wls001/p/4981203.html