zoukankan      html  css  js  c++  java
  • 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哈哈~
  • 相关阅读:
    细说进程、应用程序域与上下文之间的关系
    sql server2008添加登录账户配置权限 && 登录时18456错误
    Sql CLR
    设计模式学习篇(一)
    常用实用方法
    OOP 6大基本原则
    如何成为一个优秀的程序员
    家庭网络
    反射
    ADO.Net 事务操作
  • 原文地址:https://www.cnblogs.com/wls001/p/4981203.html
Copyright © 2011-2022 走看看