• NOIP2012普及组解题报告


    NOIP2012普及组解题报告
                            by RtPYH
    ------------------------------------------------------------------------------------------------------------------
    前言:作者是一个蒟蒻,假设对本文有建议,欢迎提出!鄙人将虚心接受。
    -------------------------------------------------------------------------------------------------------------------
                                                            1.质因数分解
    【题目描写叙述】
       给你一个由两个质数相乘得到的正整数n。求较大的质数
    【数据范围】
       n小于等于2*10^9
    【分析】
       当时有几个同学写TLE了..后来才发现他们读题不细致:n已经约定为两个质数的乘积。

    所以我们从2枚举到根号n,仅仅要n%i==0那就输出n/i

       时间复杂度(根号N)
    【代码】
    #include <iostream>
    using namespace std;
    #include <cstdio>
    
    int n,i;
    
    int main(){
       freopen("prime.in","r",stdin);
       freopen("prime.out",'w",stdout);
       cin>>n;
       for(i=2;i*i<=n;i++)
         if(n%i==0){cout<<n/i;break;}
       return 0;
    }
    

                                                         
                                                       2.寻宝
    【题目描写叙述】
       传说非常遥远的藏宝楼顶层藏着诱人的宝藏。 小明历尽千辛万苦最终找到传说中的这个藏
    宝楼,藏宝楼的门口竖着一个木板。上面写有几个大字:寻宝说明书。说明书的内容例如以下:
    藏宝楼共同拥有 N+1 层。最上面一层是顶层, 顶层有一个房间里面藏着宝藏。 除了顶层外,
    藏宝楼另有 N 层, 每层 M 个房间。这 M 个房间围成一圈并按逆时针方向依次编号为 0。…,
    M-1。当中一些房间有通往上一层的楼梯。每层楼的楼梯设计可能不同。每一个房间里有一个
    指示牌,指示牌上有一个数字 x。 表示从这个房间開始按逆时针方向选择第 x 个有楼梯的房
    间(假定该房间的编号为 k) 。从该房间上楼,上楼后到达上一层的 k 号房间。比方当前房
    间的指示牌上写着 2,则按逆时针方向開始尝试,找到第 2 个有楼梯的房间,从该房间上楼。
    假设当前房间本身就有楼梯通向上层,该房间作为第一个有楼梯的房间。
    寻宝说明书的最后用红色大号字体写着:“寻宝须知:帮助你找到每层上楼房间的指示
    牌上的数字(即每层第一个进入的房间内指示牌上的数字)总和为打开宝箱的密钥” 。


    请帮助小明算出这个打开宝箱的密钥

    【数据范围】
       对于 100%数据,有 0<N≤10000,0<M≤100。0<x≤1,000,000
    【分析】
       还是比較easyTLE的题目,关键考察是否能读题。分析题目。首先,一般的模拟思路能够得出:
        for(i=1 -) n)
          for(;tot<=i;p++)
          {  if(p的位置有楼梯)tot++;
             p%=m;
          }
        累计答案
        输出
        上述代码时间复杂度O(NX)。期望得分50分
        肯定是TLE的,我们发现数据范围有规律:m<=x
        我们又发现。因为是转圈。所以我们并不须要转x圈,仅仅须要转x mod m圈就可以,上述代码时间复杂度为:
                        O(NM)
        完了吗?不!我们发现,x mod m有可能为0,所以要特判。假设x mod m=0,那么x=m
        期望得分100分
    【代码】
    #include <iostream>
    #include <cstdio>
    using namespace std;
    
    
    const int MaxN=10010;
    const int MaxM=101;
    const int Mod=20123;
    
    
    int build[MaxN][MaxM][2],n,t[MaxN],m;
    int ans=0;
    
    
    int main(){
        freopen("treasure.in","r",stdin);
        freopen("treasure.out","w",stdout);
        scanf("%d %d",&n,&m);
        int tot,i,j,k,ii;
        for(i=1;i<=n;i++)
          for(j=0;j<m;j++)
            {
              scanf("%d %d",&build[i][j][0],&build[i][j][1]);
              if(build[i][j][0]==1)t[i]++;
            }
        scanf("%d",&k);
        for(i=1;i<=n;i++){
          tot=0;
          ans=(ans+build[i][k][1])%Mod;
          ii=build[i][k][1]%t[i];
          if(ii==0)ii=t[i];
          for(;tot<ii;k++){
            k%=m;
            if(build[i][k][0]==1)tot++;
          }
          k=(k-1+m)%m;
        }
        printf("%d",ans);
        return 0;
    }
    

                                                           3.摆花
    【题目描写叙述】
       给你n朵花可摆放的盆数以及总共能摆放的盆数。求摆放方案(同种必须相邻)
    【数据范围】
       n小于等于100
    【分析】
       阶段:背包问题
       状态:f(i,j)表示第i种花摆入容量为j的背包所能得到的方案数
       OK!
    【代码】
    </pre></div><pre name="code" class="cpp">#include <iostream>
    using namespace std;
    #include <cstdio>
    #include <cstring>
    
    const int MaxN=1001;
    const int Mod=1000007;
    
    int a[MaxN],n,m;
    int f[MaxN][MaxN],k;
    
    void init(){
    	freopen("flower.in","r",stdin);
    	freopen("flower.out","w",stdout);
    	scanf("%d %d",&n,&m);
    	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    }
    
    void DP(){
         int i,j,k;
         //f(i,j)表示前i朵花k盆放入容量为j的背包 
         f[0][0]=1;
         for(i=1;i<=n;i++)
           for(j=0;j<=m;j++)
             for(k=0;k<=j && k<=a[i];k++){
               f[i][j]+=f[i-1][j-k];
               f[i][j]%=Mod;
             }
         cout<<f[n][m];
    }
    
    int main(){
        init();
        DP();
        return 0;
    }	
    	

                                                            4.文化之旅
    【题目描写叙述】
       有一位使者要游历各国,他每到一个国家。都能学到一种文化,但他不愿意学习不论什么一
    种文化超过一次(即假设他学习了某种文化,则他就不能到达其它有这样的文化的国家) 。


    同的国家可能有同样的文化。 不同文化的国家对其它文化的看法不同,有些文化会排斥外来
    文化(即假设他学习了某种文化,则他不能到达排斥这样的文化的其它国家) 。
    现给定各个国家间的地理关系。 各个国家的文化, 每种文化对其它文化的看法。 以及这
    位使者游历的起点和终点(在起点和终点也会学习当地的文化),国家间的道路距离,试求
    从起点到终点最少需走多少路。

    【数据范围】
       n小于等于100
    【分析】
       对于求最短路问题。经常使用的算法有SPFA和Dijkstra以及Bellman_Ford。因为N的范围太小。且有
    很多限制,所以採用floyd算法求解
       我们开一个vis数组,vis[i][j]表示国家I和国家J的兼容情况。然后依据这个。来跑一遍floyd
    就可以出解
       题外话:当时比赛有神牛用搜索外加最优性剪枝AC了。蒟蒻想学习一下,望大牛能评论
    【代码】
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    const int MaxN=101; 
    const int oo=1<<25;
     
    int c[MaxN],a[MaxN][MaxN],d[MaxN][MaxN]; 
    int n,kd,m,s,t; 
    bool vis[MaxN][MaxN];
    
    int main()
    {
        freopen("culture.in","r",stdin);
        freopen("culture.out","w",stdout);
        
        scanf("%d%d%d%d%d",&n,&kd,&m,&s,&t);
        int c1,c2,i,j,k,u,v,cap;
        memset(d,0,sizeof(d));
        memset(vis,false,sizeof(vis));
        for(i=1;i<=n;i++)scanf("%d",&c[i]);
        for(i=1;i<=kd;i++)
          for(j=1;j<=kd;j++)
            scanf("%d",&a[i][j]);
        for(i=1;i<=n;i++)
          for(j=1;j<=n;j++)
            d[i][j]=oo;
        for(i=1;i<=n;i++)
          for(j=1;j<=n;j++)
          {
            c1=c[i],c2=c[j];
            if(a[c1][c2]==0)vis[j][i]=true;
          }
        for(i=1;i<=m;i++){
          scanf("%d %d %d",&u,&v,&cap);
          if(vis[u][v] && cap<d[u][v])
            d[u][v]=cap;
          if(vis[v][u] && cap<d[v][u])
            d[v][u]=cap;
        }
        for(k=1;k<=n;k++)
          for(i=1;i<=n;i++)
             for(j=1;j<=n;j++)
               if(vis[i][k]&&vis[k][j]&&d[i][j]>d[i][k]+d[k][j]) 
                 d[i][j]=d[i][k]+d[k][j];
        
        if(d[s][t]>=oo)cout<<-1;
        else cout<<d[s][t];
        return 0;
    }


  • 相关阅读:
    怎样把echarts图表做成响应式的
    检测IE浏览器兼容Edge模式及IE11
    封装微信jssdk自定义分享代码
    C# json字符串 转换成数组、集合、相应对象 sansan
    ObjectC 正确使用内存的几条法则 sansan
    c# 利用反射设置属性值 sansan
    ie6不能识别option标签的selected属性解决方案 sansan
    sql server 2005/2008 设置 sql身份验证 和 sa空密码(像sql2000一样使用)(转载) sansan
    SqlServer 日期时间格式转换 sansan
    C#获取文件大小 sansan
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/7149166.html
Copyright © 2020-2023  润新知