Codeforces Round #501 (Div. 3)

题目网址:http://codeforces.com/contest/1015 

1、D题

题意:给一个n,k,sn,k,s代表现在有nn个房子,你需要搬家kk次,搬家的总的距离为ss。每次搬家的距离定义为|xy||x−y|(x,y为第几个房子),让你构造一个转移序列,满足正好为kk次,总距离为ss.

首先我们判断:

  1. s<ks<k时一定构造不出来
  2. k(n1)<s   k∗(n−1)<s时也构造不出来

对于其他情况,一定可以构造,我们每次转移的距离选择s-kn-1中比较小的那一个,然后总距离减去走的距离,当当前走的距离加上转移的距离大于n的时候,就要往回走,然后一直走下去,就可以构造出来序列了。

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
#define MAX 200005
int ans[MAX];
ll n,k,s;
int main()
{
    cin>>n>>k>>s;
    if((n-1)*k<s||s<k)
    {
        cout<<"NO"<<endl;
        return 0;
    }
    cout<<"YES"<<endl;
    int pos=1;
    for(int i=1;i<=k;i++)
    {
        ll cnt=k-i;
        ll sum=min(n-1,s-cnt);
        s-=sum;
        if(pos+sum<=n) pos+=sum; else pos-=sum;
        ans[i]=pos;
    }
    for(int i=1;i<=k;i++)
        cout<<ans[i]<<" ";
    cout<<endl;
}

 

2、E1题

题解:题目给出如何判定一个星星的标准,请你找出有多少个星星

这题可以先预处理四个数组去记录左右上下的 星号个数,然后找星星时找最小值就行,输出用结构体记录

复杂度:O( N*M*C) C为常数

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define mod 1000000007
#define MAX 105
char s[MAX][MAX],s2[MAX][MAX];
int u[MAX][MAX],b[MAX][MAX],l[MAX][MAX],r[MAX][MAX],len[MAX][MAX];
int n,m;
struct node{

    int x, y, s;

    node(){}
    node(int nx, int ny, int ns){
        x = nx, y = ny, s = ns;
    }

} f[MAX*MAX];
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        cin>>s[i]+1;
    /*for(int i=1;i<=n;i++)
        cout<<s[i]+1;*/
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
    {
        if(s[i][j]=='*')
            l[i][j]=l[i][j-1]+1;
    }
    for(int i=1;i<=n;i++)
        for(int j=m;j>=1;j--)
    {
        if(s[i][j]=='*')
            r[i][j]=r[i][j+1]+1;
    }
    for(int j=1;j<=m;j++)
        for(int i=1;i<=n;i++)
    {
        if(s[i][j]=='*')
            u[i][j]=u[i-1][j]+1;
    }
    for(int j=1;j<=m;j++)
      for(int i=n;i>=1;i--)
    {
        if(s[i][j]=='*')
            b[i][j]=b[i+1][j]+1;
    }
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
        s2[i][j]='.';
        /*for(int i=1;i<=n;i++)
           for(int j=1;j<=m;j++)
            cout<<b[i][j];*/
        memset(len,0,sizeof(len));
        int cnt=0;
     for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
     {
         if(s[i][j]=='*')
         {
             len[i][j]=min(u[i][j],min(b[i][j],min(l[i][j],r[i][j])));
              len[i][j]--;
              if(!len[i][j])
                continue;
                f[++cnt] = node(i, j, len[i][j]);
            for(int k=i-len[i][j];k<=i+len[i][j];k++)s2[k][j]='*';
            for(int k=j-len[i][j];k<=j+len[i][j];k++)s2[i][k]='*';
         }
     }
     /*for(int i=1;i<=n;i++)
       for(int j=1;j<=m;j++)
        cout<<s2[i][j];*/
     bool flag=true;
     for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
          if(s[i][j]!=s2[i][j])
             flag=false;
     if(!flag)cout<<"-1"<<endl;
     else
     {
         cout<<cnt<<endl;
         for(int i = 1; i <= cnt; i++){
            printf("%d %d %d\n", f[i].x, f[i].y, f[i].s);

        }
     }
    return 0;
}
 
3、E2

题意:与上题一样,只不过数据从100到1000

当时上面的代码也是可以通过的,也可以做一个优化,就是再加两个数组,用类似区间求和的方法去标记星号的位置,让后就可以去掉s2,

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define mod 1000000007
#define MAX 1005
char s[MAX][MAX];
int u[MAX][MAX],b[MAX][MAX],l[MAX][MAX],r[MAX][MAX],len[MAX][MAX],w[MAX][MAX],e[MAX][MAX];
int n,m;
struct node{

    int x, y, s;

    node(){}
    node(int nx, int ny, int ns){
        x = nx, y = ny, s = ns;
    }

} f[MAX*MAX];
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        cin>>s[i]+1;
    /*for(int i=1;i<=n;i++)
        cout<<s[i]+1;*/
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
    {
        if(s[i][j]=='*')
            l[i][j]=l[i][j-1]+1;
    }
    for(int i=1;i<=n;i++)
        for(int j=m;j>=1;j--)
    {
        if(s[i][j]=='*')
            r[i][j]=r[i][j+1]+1;
    }
    for(int j=1;j<=m;j++)
        for(int i=1;i<=n;i++)
    {
        if(s[i][j]=='*')
            u[i][j]=u[i-1][j]+1;
    }
    for(int j=1;j<=m;j++)
      for(int i=n;i>=1;i--)
    {
        if(s[i][j]=='*')
            b[i][j]=b[i+1][j]+1;
    }
        /*for(int i=1;i<=n;i++)
           for(int j=1;j<=m;j++)
            cout<<b[i][j];*/
        memset(len,0,sizeof(len));
        memset(w,0,sizeof(w));
        memset(e,0,sizeof(e));
        int cnt=0;
     for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
     {
         if(s[i][j]=='*')
         {
             len[i][j]=min(u[i][j],min(b[i][j],min(l[i][j],r[i][j])));
              len[i][j]--;
              int t=len[i][j];
              if(!len[i][j])
                continue;
                f[++cnt] = node(i, j, len[i][j]);
           w[i][j-t]++,w[i][j+t+1]--;
           e[i-t][j]++,e[i+t+1][j]--;
         }
     }
     for(int i=1;i<=n;i++)
       for(int j=1;j<=m;j++)
        w[i][j]+=w[i][j-1],e[i][j]+=e[i-1][j];
     bool flag=true;
     for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
          if(s[i][j]=='*'&&!w[i][j]&&!e[i][j])
             flag=false;
     if(!flag)cout<<"-1"<<endl;
     else
     {
         cout<<cnt<<endl;
         for(int i = 1; i <= cnt; i++){
            printf("%d %d %d\n", f[i].x, f[i].y, f[i].s);

        }
     }
    return 0;
}

4、F题

这道过的人较少,以后再补

 

posted @ 2018-08-06 00:51  better46  阅读(201)  评论(0编辑  收藏  举报