18.3.1

写在前面

要到3.3才开学,这几天在机房进入福州集训模式。。。
就是上午考试,下午讲,然后自己敲代码。
其实感觉还行。。
昨天的到时候补上,因为T4老刘数据不正确。所以不能算完成。
情况如图
这里写图片描述
这里写图片描述
啊!疯狂掉Rating。。
看题目吧。

T1

题面

1.简单题
(zizhen.pas/c/cpp)
【问题描述】
给定数轴上的N个点,求这些点到其他点的距离总和S。

【输入】
第一行一个整数N。
接下来N行每行一个整数,表示每个点的坐标xi。

【输出】
一个整数S。

【输入输出样例1】
zizhen.in zizhen.out
5
1
5
3
2
4 40

【输入输出样例2】
zizhen.in zizhen.out
8
10
20
30
40
50
60
70
80 1680

【数据范围】
对于30%的数据,1≤N≤10000
对于50%的数据,保证1≤xi。
对于70%的数据,保证1≤N≤300000,且任意两点的坐标不相同。
对于100%的数据,保证1≤N≤3000000,|xi|≤2^15-1。

描述

就是求每点与其他点距离总和。。
我的解法有点像差分。
利用各数排序后的差值。
有差值也就是右边比左边普遍高这么多。也就是总距离加上(差值乘以i乘以(n-i)再乘上2)就可以了。

题解

#include<bits/stdc++.h>
using namespace std;
inline long long read()
{
    long long sum=0;char c=getchar();
    for(;c<'0'||c>'9';c=getchar());
    for(;c<='9'&&c>='0';c=getchar())
      sum=(sum<<1)+(sum<<3)+c-48;
    return sum;
}
long long n,ans=0;
long long a[3000010]={};
void init()
{
    n=read();
    for(int i=1;i<=n;i++)
      a[i]=read();
}
void work()
{
    sort(a+1,a+n+1);
    for(int i=1;i<n;i++)
      a[i]=a[i+1]-a[i];
    for(int i=1;i<n;i++)
      ans+=a[i]*i*(n-i)*2;
}
int main()
{
    init();
    work();
    cout<<ans;
    return 0;
}

反思

。。。
为什么我只有60??
因为a数组的3000010.
我写成了300010!!!
一波失误。。。
不能再错。

T2

题面

2.激光通讯
(laser.pas/c/cpp)
【问题描述】
海亮教育园的oiers有了新的通讯工具,采用最先进的系统——激光通讯系统,这样可以让他们在整个校园无延时的进行通讯。
海亮教育园校园被设计为由W*H个点组成的网格。(1 <= W <= 100; 1 <= H <= 100)这套系统要求类似视线连通以确保维持通讯,当然了,校园里还有一些建筑和树,这些东西会干扰通讯,但是oiers早有准备,他们购买了一些斜放的反光镜(如下图中的”/”和”\”),这些镜子能通过反射把激光束扭转90度,下面是问题的一个图解。
在这个地图中H=8,W=7,正在通讯的两名oiers用符号”C”表示,可通讯区域用”.”表示,障碍物用”*”表示:
这里写图片描述
确定最少需要安放几个反光镜(数目用M表示),才能保证这两个人之间的激光通讯,注意所给的数据一定有解。

【输入】
第1行有两个空格隔开的整数:W,H;
第2~H+1行为完整的校园。
【输出】
一行,一个整数M,即反光镜的个数。
【输入输出样例1】
laser.in
7 8
…….
……C
……*
.
….*..
….*..
.C..*..
…….

laser.out
3

【数据范围】
30% n,m<=30.
50% n,m<=50

描述

就是可以使用平面镜改变通讯方向。
求需要最少几只镜子,能到达终点。
根据题解才知道,使用改版的bloodfill。。
每次bfs同行同列的进行染色。
这样的话很容易可以求出。
这里写图片描述

题解

#include<bits/stdc++.h>
using namespace std;
int m,n,xx,yy;
char a[110][110];
bool vis[110][110]={};
struct note
{
    int x,y,sum;
}q[1000010];
void init()
{
    char c;
    scanf("%d%d",&m,&n);
    for(int i=1;i<=n;i++)
      {
        c=getchar();
        for(int j=1;j<=m;j++)
          {
            a[i][j]=getchar();
            if (a[i][j]=='C')
              xx=i,yy=j;
          }
      }
    for(int i=1;i<=m;i++)
      a[0][i]='*',a[n+1][i]='*';
    for(int i=1;i<=n;i++)
      a[i][0]='*',a[i][m+1]='*';
}
void work()
{
    int head=0,tail=1;
    q[1].x=xx;
    q[1].y=yy;
    q[1].sum=0;
    vis[xx][yy]=1;
    while (++head<=tail)
      {
        for(int i=q[head].x;i<=n;i++)
          if (!vis[i][q[head].y])
          {
            if (a[i][q[head].y]=='*')
              break; 
            if (a[i][q[head].y]=='C')
              {
                  cout<<q[head].sum;
                  return ;
              }
            q[++tail].x=i;
            q[tail].y=q[head].y;
            q[tail].sum=q[head].sum+1;
            vis[i][q[head].y]=1;
          }
        for(int i=q[head].x;i>=1;i--)
          if (!vis[i][q[head].y])
          {
            if (a[i][q[head].y]=='*')
              break;
            if (a[i][q[head].y]=='C')
              {
                  cout<<q[head].sum;
                  return ;
              }
            q[++tail].x=i;
            q[tail].y=q[head].y;
            q[tail].sum=q[head].sum+1;
            vis[i][q[head].y]=1;
          }
        for(int i=q[head].y;i>=1;i--)
          if (!vis[q[head].x][i])
          {
            if (a[q[head].x][i]=='*')
              break;
            if (a[q[head].x][i]=='C')
              {
                  cout<<q[head].sum;
                  return ;
              }
            q[++tail].x=q[head].x;
            q[tail].y=i;
            q[tail].sum=q[head].sum+1;
            vis[q[head].x][i]=1;
          }
        for(int i=q[head].y;i<=m;++i)
          if (!vis[q[head].x][i])
          {
            if (a[q[head].x][i]=='*')
              break;
            if (a[q[head].x][i]=='C')
              {
                  cout<<q[head].sum;
                  return ;
              }
            q[++tail].x=q[head].x;
            q[tail].y=i;
            q[tail].sum=q[head].sum+1;
            vis[q[head].x][i]=1;
          }
      }
}
int main()
{
    init();
    work();
    return 0;
}

T3

题面

3.巡逻
(patrol.pas/c/cpp)
【问题描述】
海亮教育园的保卫科每天晚上都要进行巡逻,而实验楼是机房所在地,是要必须巡逻的。
为了更好的描述问题,现在我们把海亮教育园抽象成一个图,这个图有N个点,M条有向边,保卫科在1号点,一号实验楼在2号点。每天巡逻必须从1号点出发,到达2号点再回到1号点,当然这个路径是包含自己选择的。
因为今天只有1个保安,没有其他人监督,并且在晚上一个人巡逻是很痛苦的事情,现在他想要在巡逻的过程中,经过的不同的点的个数最小,如果能完成这个任务,你的rp可以增加!
【输入】
第一行有两个整数N和M (2 ≤ N ≤ 100, 2 ≤ M ≤ 200)。
接下来M行,每行两个整数A和B (1 ≤ A, B ≤ N),保证不会有重边。

【输出】
只有1个整数,表示最少经过的不同的点的个数。

【输入输出样例1】
patrol.in patrol.out
6 7
1 3
3 4
4 5
5 1
4 2
2 6
6 3 6
{路径是1 -> 3 -> 4 -> 2 -> 6 -> 3 -> 4
-> 5 -> 1. 经过6个城市。}
【输入输出样例2】
patrol.in
9 11
1 3
3 4
4 2
2 5
5 3
3 6
6 1
2 7
7 8
8 9
9 1

patrol.out
6
【数据范围】
20%数据保证 N<=20.

描述

dfs先找2,再找1.
求一个路径经过最少点。

题解

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    int sum=0;char c=getchar();
    for(;c<'0'||c>'9';c=getchar());
    for(;c<='9'&&c>='0';c=getchar())
      sum=(sum<<1)+(sum<<3)+c-48;
    return sum;
}
int t=0,n,m,ans=100000000;
struct note
{
    int y,next;
}a[210];
int linkk[110]={};
bool vis[110]={};
bool f[110]={};
void insert(int x,int y)
{
    a[++t].y=y;
    a[t].next=linkk[x];
    linkk[x]=t;
}
void init()
{
    n=read();
    m=read();
    int x,y;
    for(int i=1;i<=m;i++)
      {
        x=read();
        y=read();
        insert(x,y);
      }
}
void dfs2(int now,int sum)
{
    if (sum>=ans) return ;
    if (now==1)
      {
        ans=min(ans,sum);
        return ;
      }
    for(int i=linkk[now];i;i=a[i].next)
        if (!vis[a[i].y])
        {
          vis[a[i].y]=1;
          if (!f[a[i].y]) dfs2(a[i].y,sum+1);
            else dfs2(a[i].y,sum);
          vis[a[i].y]=0;
        }
}
void dfs1(int now,int sum)
{
    if (sum+1>=ans) return ;
    if (now==2)
      {
        memset(vis,0,sizeof(vis));
        vis[2]=1;
        dfs2(now,sum);
        return ;
      }
    for(int i=linkk[now];i;i=a[i].next)
        if (!f[a[i].y]) 
          {
            f[a[i].y]=1;
            dfs1(a[i].y,sum+1);
            f[a[i].y]=0;
          }
}
int main()
{
    init();
    f[1]=1;
    dfs1(1,1);
    cout<<ans;
    return 0;
}

反思

不能怕麻烦。
多分几步走。
如果怕麻烦反而可能更麻烦。。
欲速则不达,不要自以为是。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值