NOIP2015复赛题解报告答案以及代码

第一题,直接是暴力模拟。

#include
using namespace std;
int a[20002];
int s[20002];
int main()
{
    int cnt=1;
    for(int i=1;i<10001;i++)
    {
        for(int j=0;j10000)break;
    }
    int k;
    cin>>k;
    cout<

第二题,也是暴力,每次循环周围的,这里用int保存图直接累加地雷比较方便,而答案用char输出:

#include
using namespace std;
int a[105][105];
char ans[105][105];
int main()
{
    int n,m;
    cin>>n>>m;
    char temp;
    for(int i=1;i<=n;i++)
       for(int j=1;j<=m;j++)
        {
            cin>>temp;
            if(temp=='*')
                a[i][j]=1;
        }

     for(int i=1;i<=n;i++)
       for(int j=1;j<=m;j++)
       {
           if(a[i][j]==1)
             ans[i][j]='*';
           else
            ans[i][j]=char('0'+a[i-1][j-1]+a[i-1][j]+a[i][j-1]+a[i+1][j]+a[i][j+1]+a[i+1][j+1]+a[i-1][j+1]+a[i+1][j-1]);
       }
     for(int i=1;i<=n;i++)
       {
           for(int j=1;j<=m;j++)
              cout<

第三题,俩个条件,一看y没有参加积分贡献,只是起到限制作用,一分析,知道表示x,z要么都是奇数,要不都是偶数。所以先按小标直接分成俩个集合,一奇一偶,然后相同的处理方式,暴力方法很容易想到(这样可以得40分),俩俩枚举若是相同颜色就累加积分,这样大数据会超时,所以这样处理:先按颜色分类,颜色一样的在一维(可以建立一个二维数组,每一维放一种颜色),这样一维之中任意俩个都符合条件,这样sum((di+dj)*(wi+wj)),就可以转为,(n-1)*sum(diwi)+sum(di)*sum(wi)-sum(diwi),其中di是下标,wi是它的对应值,这样就是O(n)的时间复杂度了。代码:

#include
#include
#include
using namespace std;
struct node
{
    long long id;
    long long w;
    long long cl;
};
node a[200000];
int main()
{
    int n,m;
     scanf("%d%d",&n,&m);
     vector >v1(m+1),v0(m+1);
     for(int i=1;i<=n;i++)
     {
         a[i].id=i;
         scanf("%lld",&a[i].w);
     }
      for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i].cl);
            if(i%2==0)
               v0[a[i].cl].push_back(a[i]);
            else
               v1[a[i].cl].push_back(a[i]);
        }
       long long ans=0;
        for(int i=1;i


第四题,这样想:前N+1的最优解,必然包括前N次的最优解(反证法很容易证明),所以每次只要新加入一个最大增加疲劳值的即可,这样做比较暴力是,平方的算法只能得小数据部分,对于大数据,这样是会超时,所以,这样考虑,每次增加的点,若比最远距离远,那么,增加疲劳值是2*(s【i】)+a【i】,若是比最远距离近,那就只增加a【i】,所以只要维护这俩个优先队列,按这俩个关键字,大的在前,每次比较这两中大的一个加入即可,这样复杂度是n*log(n)。

代码之后有时间再上传。



你可能感兴趣的:(杂题)